我显然对条件变量以及如何使用它们有错误的理解。我的意图是只有一个生产者和多个消费者线程,但是我可以证明我对于一个生产者和一个消费者的问题。
有一个名为work
的共享变量,该共享变量受互斥量和条件变量保护。生产者设置work
变量并发出信号,表明它已经准备好了,但是消费者线程永远无法运行?
如果程序正常运行,则应打印this line never get's printed
,但我却得到consumer never did work...giving up
。任何帮助将不胜感激
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int work = 0;
void* consumer(void* ptr) {
pthread_mutex_lock(&mutex);
while(1) {
pthread_cond_wait(&cond, &mutex);
if (work == 0)
continue;
printf("this line never get's printed\n");
work = 0;
}
return NULL;
}
int main() {
pthread_t thr;
pthread_create(&thr, NULL, consumer, NULL);
sleep(1); /* give consumer moment to lock mutex */
for(int ndx=0; ndx < 50; ndx++) {
pthread_mutex_lock(&mutex);
if (work == 1) {
printf("consumer never did work...giving up\n");
return -1;
}
work = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
return 0;
}
编译:
$ g++ -pthread simple.cpp -o simple
在Debian 7.9上运行(也在CentOS 6.7上复制)
$ getconf GNU_LIBPTHREAD_VERSION
NPTL 2.13
$ g++ --version
gcc version 4.7.2 (Debian 4.7.2-5)
最佳答案
您的问题是,尽管您的使用者线程在继续之前等待生产者进行生产,但是生产者同样没有等待使用者进行消耗。仅仅因为生产者调用pthread_cond_signal()
并不意味着将立即调度等待该条件变量的线程,特别是因为生产者线程在调用时已锁定了相关的互斥锁。使用者无法恢复,直到它可以锁定互斥体为止,并且完全有理由的是,尽管生产者线程将其解锁,但它也会循环循环并在使用者继续使用之前再次锁定它。
您可以使用相同的条件变量或与同一互斥锁关联的另一个变量,以允许使用者向生产者发出可以继续进行的信号。
关于c++ - 对pthread_cond_wait()的理解有误的协助,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32588128/