制片人 - 消费者&条件变量程序陷入无限循环

时间:2016-03-07 21:01:56

标签: c concurrency infinite-loop

当我用usleep运行我的程序(在C中运行)时,它会陷入无限循环。没有睡眠,程序不会同时运行。任何帮助都感激不尽。 该计划应该允许生产者在消费者同时食用食物的同时制作食物。添加约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;
}

1 个答案:

答案 0 :(得分:1)

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

newItem -> next = NULL;

同样在你的removeItem(...)函数中;

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

同样正如@EOF在上面的评论中所说,使用互斥锁来保护生产者(...)和消费者(...)例程中对缓冲区&gt;大小的访问。例如;

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

在解决了所有这些问题之后,您的生产者似乎最后退出,让队列完全填满。不确定你期望的行为。