为什么信号灯的条件/互斥体实现需要"wait()"函数中的"while"循环?

Why does a condition/mutex implementation of a semaphore require a "while" loop in its "wait()" function?

本文关键字:wait 函数 while 循环 条件 信号灯 为什么 实现      更新时间:2023-10-16

我一直在仔细研究以下SO问题的公认答案:C++0x没有信号量?如何同步线程?

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

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

我正在努力理解while(!count_)条件的目的。

另一个SO问题(信号量的这种实现是如何工作的?)的答案表明,当对条件变量调用notify_one()时,可能会唤醒在该条件变量上等待的多个线程,因此需要while循环。我想确认一下——这是完整和/或正确的答案,还是while循环有必要的其他原因?

如果有多个线程唤醒,那么哪个线程拥有互斥体?我想得越多,如果多个线程由于对notify_one()的一次调用而唤醒,那么定义就越不明确。两个被唤醒的线程都不可能看到count_值高于0,并继续递减count_,导致count_值小于0,从而破坏信号量的目的(和正确性)吗?

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

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