当缓冲区小于生产者的输入时,生产者/消费者似乎陷入僵局

我创建了一个循环缓冲区,其中有多个客户端写入(最后我希望它们将不同大小的消息写入)到缓冲区中。 服务器将它们读出来。 它基于消费者/生产者问题中的代码:

#include  #include  #include  #include  #include  #define BUFFER_SIZE 10 struct cBuf{ char *buf; int size; int start; int end; pthread_mutex_t mutex; pthread_cond_t buffer_full; pthread_cond_t buffer_empty; }; struct cBuf cb; void buf_Init(struct cBuf *cb, int size) { int i; cb->size = size + 1; cb->start = 0; cb->end = 0; cb->buf = (char *)calloc(cb->size, sizeof(char)); } void buf_Free(struct cBuf *cb) { free(cb->buf); } int buf_IsFull(struct cBuf *cb) { return (cb->end + 1) % cb->size == cb->start; } int buf_IsEmpty(struct cBuf *cb) { return cb->end == cb->start; } int buf_Insert(struct cBuf *cb, char *elem) { int i,j; pthread_mutex_lock(&(cb->mutex)); for (i=0; i buffer_empty),&(cb->mutex)); } cb->buf[cb->end] = elem[i]; cb->end = (cb->end + 1) % cb->size; printf("%c-",elem[i]); } pthread_cond_signal(&(cb->buffer_full)); pthread_mutex_unlock(&(cb->mutex)); return 0; } int buf_Read(struct cBuf *cb, char *out) { int i,j; pthread_mutex_lock(&(cb->mutex)); if (buf_IsEmpty(cb))printf("\nConsumer (buf_Read) is waiting "); while(buf_IsEmpty(cb)){ pthread_cond_wait(&(cb->buffer_full),&(cb->mutex)); } for (i=0;istart == cb->end) break; out[i] = cb->buf[cb->start]; cb->buf[cb->start] = '_'; cb->start = (cb->start + 1) % cb->size; printf("%c-",out[i]); } pthread_cond_signal(&(cb->buffer_empty)); pthread_mutex_unlock(&(cb->mutex)); return 0; } void * client(void *cb){ pthread_detach(pthread_self()); struct cBuf *myData; myData = (struct cBuf*) cb; char input[]="Hello World!"; if (buf_Insert(myData, input)) printf("\n"); return 0; } int main(void) { char out[60]; pthread_t thread; int i; pthread_cond_init(&(cb.buffer_full),NULL); pthread_cond_init(&(cb.buffer_empty),NULL); buf_Init(&cb, BUFFER_SIZE); for (i = 0; i<1; i++){ if(pthread_create (&thread,NULL, client, (void *) &cb) !=0){ #ifdef DEBUG printf("\nDEBUG (Main Thread) - Error while creating thread"); #endif } else { #ifdef DEBUG printf("\nDEBUG (Main Thread) - Thread created"); #endif } } while (1){ if (buf_Read(&cb,out)) printf ("succes"); } buf_Free(&cb); return 0; } 

当缓冲区大于单个客户端的消息时(通过使buffer_size更大,例如16),它主要起作用。 然而,当我把它缩小时,它似乎陷入僵局,即使经过大量研究,我也无法弄清楚原因。 当我在调试器中运行代码时,代码似乎停在线上

 pthread_cond_wait(&(cb->buffer_empty),&(cb->mutex)); 

为什么代码在这里停止,如何防止它停止?

您是否以单数forms说“小于消息”? 如果缓冲区的大小不足以存储甚至一条消息,那么生产者将停止将其写入队列中途,并且永远不会通知消费者它有消费的东西。

对代码的简要扫描似乎证实 – 如果即使一条消息无法写入,也会在写入循环中阻塞,并且在函数结束时不会进入pthread_cond_signal调用,因此您永远不会通知消费者它无法释放缓冲区。

这个问题是主要的。 消费者可以开始消费的基本单位必须适合队列。 您可以通过两种方式解决问题 – 确保缓冲区对于消息足够大,或者使消息可以在较小的单元中处理,并在每个单元后通知使用者( pthread_cond_signal )。