2016-03-07 109 views
0

當我用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; 
} 
+0

看起來你忘記了爲你的bufferBox互斥體調用pthread_mutex_init()。 – cleblanc

+0

對多線程中的'buffer-> size'進行非同步,非只讀,非原子訪問 - >未定義的行爲。 – EOF

回答

1

你需要小心使用它,例如之前初始化所有數據的addFood(...)在頂部例行添加這樣一行

newItem -> next = NULL; 

同樣,在你的removeItem( ...)功能;

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

另外,作爲@EOF在他的評論中說,上述使用互斥來保護訪問buffer->尺寸在生產商(...)和消費者(...)例程。例如;

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

解決了所有這些問題後,您的生產者似乎退出最後一個隊列完全退出隊列。不知道你期望什麼行爲。