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

5

我一直在认真研究以下 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() 时,可能会唤醒等待该条件变量的不止一个线程,因此需要使用 while 循环。我想确认一下 - 这是完整和/或正确的答案吗?还是还有其他原因需要使用 while 循环?
如果有多个线程被唤醒,哪个线程拥有互斥锁?我越想越觉得这个问题定义不清楚,如果由于单个 notify_one() 调用而唤醒了两个线程,那么两个线程都可以看到 count_ 值大于0,并继续将其减少,导致 count_ 值小于0,从而破坏了信号量的目的(和正确性)是否有可能?
1个回答

3

可能存在虚假唤醒,或者由于实现细节,notify_one可能会唤醒多个线程,正如您已经提到的那样。

唤醒多个线程并不意味着它们都可以同时进入受保护的部分,这只是意味着当ThreadA释放锁时,与ThreadA一起被唤醒的ThreadB也可以进入受保护的部分。此时,ThreadA已经完成了它的工作,所以ThreadB将不会看到与ThreadA发现的相同状态的count变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接