我正在编写一个简单的生产者/消费者程序来更好地理解c ++和多线程。 在我运行消费者的线程中,我有前两行:
pthread_cond_wait(&storageCond, &storageMutex);
pthread_mutex_lock(&storageMutex);
但程序陷入困境,可能是一个僵局。 然后我换了一行:
pthread_mutex_lock(&storageMutex);
pthread_cond_wait(&storageCond, &storageMutex);
它有效。 有人可以帮我理解为什么这有效,而前者没有?
谢谢。
答案 0 :(得分:5)
从pthread_cond_wait联机帮助页(http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_wait.html):
它们是通过调用线程锁定的互斥锁调用的,或者是未定义的 行为将导致。
我建议您使用一些好的包装器库,如boost::threads
,或者当您可以访问C ++ 11时,可以使用std::
线程工具。由于它们使用像RAII这样的东西,因此它们更易于处理,尤其是在没有经验的线程编程时。
答案 1 :(得分:1)
这有点简化了,但你基本上需要锁定你正在使用的互斥锁才能进行条件等待 - 就像多线程竞争条件保护一样。如果您需要对原因有一个很好的描述,请查看UNIX手册页中的“man pthread_cond_wait”并给出一个很好的长篇演讲:)
pthread_cond_wait(&storageCond, &storageMutex); //Wants mutex you don't have locked.
pthread_mutex_lock(&storageMutex); //Get mutex after its too late.
pthread_mutex_lock(&storageMutex); //Get mutex first.
pthread_cond_wait(&storageCond, &storageMutex); //Do cond wait with mutex you have.
答案 2 :(得分:1)
一旦线程从条件变量wait恢复,它将重新获取互斥锁。这就是第一个示例程序卡住的原因。
我的想法是始终在互斥锁中执行cond_wait()。 cond_wait()将放弃锁并以原子方式开始等待(这样你就不会错过来自另一个线程的cond_signal())并且当发出信号时,cond_wait()将重新获取互斥锁以确保你的关键部分只有一个线程在里面跑。
HTH,这种锁定方案称为Monitor。