Producer–Consumer & Condition Variables 程序陷入无限循环

Producer–Consumer & Condition Variables program gets stuck in a infinite loop

当我 运行 我的程序(运行ning 在 C 中)使用 usleep 时,它陷入无限循环。如果没有 usleep,程序不会同时 运行。任何帮助都感激不尽。 该计划应该允许生产者制作食物,而消费者同时获取食物。添加大约 5 个项目后我的程序卡住了并停止。我想这可能是一个线程没有被解锁,但我想不通。

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h>
#include <time.h>
              // rc stands for return code
#define NUM_THREADS 4 // declare consumers
#define NUM_PRODUCERS 2 // declare producers
#define MAX_BUFFER 10 // declare max buffer
pthread_mutex_t bufferBox; // delcare buffer

struct foodItem{           // structure for food
   int serialCode;
   int producer;
   struct foodItem * next;  

};
struct buffer{            // Structure for buffer
  int size;
  struct foodItem * head;
};
struct buffer * myBuffer; 
void addFood(int producer, struct buffer * buffer);
void removeItem(struct buffer * buffer);

int serial;

void addFood(int producer, struct  buffer * buffer){       // ADD TO BUFFER FUNCTION

    struct foodItem * newItem = malloc(sizeof(struct foodItem));
        newItem -> producer = producer;
    newItem -> serialCode = serial;

    if(buffer->size==0){
    buffer-> head = newItem;
        buffer->size++;
    printf("item added serial%d\n",serial);
    serial++;
    }
    else{

    struct foodItem * item = buffer ->head;
    while(item->next != NULL ){
        item = item-> next;
        }
        item ->next =newItem;
            buffer->size++;
        printf("item added serial%d\n",serial);
        serial++;   
    }

}
void removeItem(struct buffer * buffer){            //REMOVE FROM BUFFER FUNCTION
    if(buffer->size ==1){
       free(buffer->head);

    }
    else{
             struct foodItem * temp = buffer -> head;
         buffer -> head = buffer ->head->next;
         free(temp);    
    }
    buffer->size--;
    printf("item removed\n");
}
void *Producers(void *threadid){
    int i =11;
       while(i>0){
         if(myBuffer->size < MAX_BUFFER){ 
           pthread_mutex_lock(&bufferBox);
       addFood((int)threadid,  myBuffer);
       addFood((int)threadid,  myBuffer);
       pthread_mutex_unlock(&bufferBox);
      usleep(20000);    
         }   
    else{
    printf("OverFlow\n");
    } 
      i--;
   }
   pthread_exit(NULL); 
}

void *Consumers(void *threadid) {
        usleep(20000);
    int i =6;
    while( i >0){

        if(myBuffer->size > 0){ 
           pthread_mutex_lock(&bufferBox);
       removeItem(myBuffer);

       pthread_mutex_unlock(&bufferBox);
      usleep(15000);
         }   
    else{
    printf("UnderFlow\n");
    }
     i--;
}
    pthread_exit(NULL);


} 




int main (int argc, const char * argv[]) { 
    pthread_t consumers[NUM_THREADS]; 
        pthread_t producers[NUM_PRODUCERS];
    long rc,t,i;    
    int size =0;
        myBuffer = malloc(sizeof(struct buffer));

        for (t=0;t<NUM_PRODUCERS;t++) { 

        printf("Creating Producers %ld\n",t); 
    rc = pthread_create(&producers[t],NULL,Producers,(void *)t); // initial producer
        if (rc) { 
            printf("ERROR return code from pthread_create(): %ld\n",rc); 
            exit(-1); 
        } 
    } 

    //usleep(10000);
    for (t=0;t<NUM_THREADS;t++) { 

        printf("Creating Consumers %ld\n",t); 
    rc = pthread_create(&consumers[t],NULL,Consumers,(void *)t); // initial consumers
        if (rc) { 
            printf("ERROR return code from pthread_create(): %ld\n",rc); 
            exit(-1); 
        } 
    } 
    // wait for threads to exit 
    for(t=0;t<NUM_THREADS;t++) { 
        pthread_join(producers[t], NULL); 
    }

    // wait for threads to exit 
    for(t=0;t<NUM_THREADS;t++) { 
        pthread_join(consumers[t], NULL); 
    } 
    return 0;
}

您需要在使用之前小心初始化任何数据,例如您的 addFood(...) 例程在顶部添加这样一行

newItem -> next = NULL;

与您的 removeItem(...) 函数类似;

if(buffer->size ==1){
    free(buffer->head);
    buffer->head = NULL;
}

正如@EOF 在他上面的评论中所说,在您的 Producers(...) 和 Consumers(...) 例程中使用互斥锁来保护对 buffer->size 的访问。例如;

pthread_mutex_lock(&bufferBox);
if(myBuffer->size < MAX_BUFFER) { 
....
pthread_mutex_unlock(&bufferBox);

在解决所有这些问题后,您的制作人似乎最后退出,队列已满。不确定您期望的行为。