我一直在仔细研究以下 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_
,导致 count_
小于 0 的值,并且违背了信号量的目的(和正确性)?
最佳答案
可能有 spurious wakeups ,或者 notify_one
可能会因为实现细节而唤醒多个线程,正如您已经提到的那样。
虽然唤醒多个线程并不意味着它们都可以同时进入 protected 部分,它只是意味着当ThreadA释放锁时,ThreadB(在前面的例子中与ThreadA一起被唤醒)也可以进入 protected 部分。此时 ThreadA 已经完成了它的工作,因此 ThreadB 不会看到 count
变量处于与 ThreadA 发现它时相同的状态。
关于c++ - 为什么信号量的条件/互斥实现在其 "while"函数中需要一个 "wait()"循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13412110/