我显然对条件变量以及如何使用它们有错误的理解。我的意图是只有一个生产者和多个消费者线程,但是我可以证明我对于一个生产者和一个消费者的问题。

有一个名为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/

10-12 20:39