我有一个工作线程处理工作项的队列。
//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
吗?如果是的话,这个信号会在哪里?以及我的其他工作人员的样子(规范形式)?
答案 0 :(得分:1)
我看到了解决问题的两种可能方法:
一个。为列表引入另一个条件变量(例如signalList
),以便consumer2
线程等待它上面的事件。在这种情况下,consumer1
必须发出两次信号:一次在queueSignalPop
上,一次在signalList
上:
// 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;
}
我建议采用第一种方法,因为它更好地区分每个条件变量的目的。