为什么信号量的条件/互斥量实现在其“wait()”函数中需要“while”循环?

时间:2012-11-16 07:20:43

标签: c++ boost

我一直在仔细研究以下SO问题的接受答案:C++0x has no semaphores? How to synchronize threads?

在该答案的信号量实现中,这是wait()函数的实现:

void wait()
{
    boost::mutex::scoped_lock lock(mutex_);
    while(!count_)
        condition_.wait(lock);
    --count_;
}

我试图理解while(!count_)条件的目的。

另一个SO问题(How does this implementation of semaphore work?)的答案表明,当条件变量调用notify_one()时, MORE THAN ONE 线程可能会等待条件变量将被唤醒 - 因此需要while循环。我想确认一下 - 是完整的和/或正确的答案,还是有其他原因需要while循环?

如果多个线程被唤醒,哪个线程拥有互斥锁?我想的越多,如果由于单个调用notify_one()而多个线程可以唤醒,则看起来越不明确。 BOTH唤醒线程是否不可能将count_值看作高于0,并继续递减count_,导致count_值小于0,并且打败了信号量的目的(和正确性)?

1 个答案:

答案 0 :(得分:3)

正如您已经提到的,由于实施细节,可能会有spurious wakeupsnotify_one唤醒多个线程。

唤醒多个线程并不意味着虽然所有线程都可以同时进入受保护部分,但这只意味着当ThreadA释放锁定时,ThreadB(在前面的示例中与ThreadA一起唤醒)也可以进入受保护的部分。到目前为止,ThreadA已经完成了它的工作,所以ThreadB不会看到count变量处于与ThreadA找到它相同的状态。