2013-05-14 81 views
1

我有一個工作線程處理工作項的隊列。現在pthread同步兩個消費者一個生產者

//producer 
void push_into_queue(char *item) { 
    pthread_mutex_lock (&queueMutex); 
    if(workQueue.full) { // full } 
    else{ 
     add_item_into_queue(item); 
     pthread_cond_signal (&queueSignalPush); 
    } 
    pthread_mutex_unlock(&queueMutex); 
} 
// consumer1 
void* worker(void* arg) { 
    while(true) { 
     pthread_mutex_lock(&queueMutex); 
     while(workQueue.empty) 
      pthread_cond_wait(&queueSignalPush, &queueMutex); 

     item = workQueue.front; // pop from queue 
     add_item_into_list(item); 

     // do I need another signal here for thread2? 
     pthread_cond_signal(&queueSignalPop); 
     pthread_mutex_unlock(&queueMutex); 
    } 
    return NULL; 
} 
pthread_create (&thread1, NULL, (void *) &worker, NULL); 

我想有thread2消費插入add_item_into_list()的數據,但只有當項目已被添加到列表中。請注意,該列表是永久性的,不能在整個程序期間清空或釋放。

所以我的問題是:我需要另一個pthread_cond_signal ?,如果是的話,這個信號會去哪裏?以及我的其他工作人員如何看起來像(典型形式)?

回答

1

我看到解決問題的兩個可能的途徑:

一個。爲列表引入另一個條件變量(例如signalList),以便consumer2線程將等待其上的事件。在這種情況下consumer1有信號兩次:上一次signalListqueueSignalPop,一旦:

// consumer1 
void* worker(void* arg) { 
    while(true) { 
     // ... 
     pthread_cond_signal(&queueSignalPop); 
     pthread_cond_signal(&signalList); 
     pthread_mutex_unlock(&queueMutex); 
    } 
    return NULL; 
} 

灣使用現有條件queueSignalPop內部變量consumer2等待事件,並使用廣播代替consumer1中的信號。廣播是指所有的條件變量等待的線程將被喚醒:

// consumer1 
void* worker(void* arg) { 
    while(true) { 
     // ... 
     pthread_cond_broadcast(&queueSignalPop); 
     pthread_mutex_unlock(&queueMutex); 
    } 
    return NULL; 
} 
// consumer2 
void* worker2(void* arg) { 
    while(true) { 
     while(list.empty) 
      pthread_cond_wait(&queueSignalPop, &queueMutex); 
     // ... 
    } 
    return NULL; 
} 

我提議去的第一種方法,因爲它更好的區分每個條件變量的目的。

+0

感謝這兩個建議,正是我所期待的。 – user1024718 2013-05-14 12:49:07