2013-05-14 61 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

相关问题