3

在此示例中将唤醒多少个等待线程:

第一个线程

void wakeUp2Threads()
{
    std::unique_lock<std::mutex> lock(condvar_mutex);

    condvar.notify_one();
    condvar.notify_one();
}

第二个线程

{
    std::unique_lock<std::mutex> lock(condvar_mutex);

    condvar.wait(lock); <- 2nd thread has entered here before 1st thread entered wakeUp2Threads.
}

第三个线程(与第二个相同):

{
    std::unique_lock<std::mutex> lock(condvar_mutex);

    condvar.wait(lock); <- 3rd thread has entered here before 1st thread entered wakeUp2Threads.
}

是否可以保证在此示例中两个通知都将传递到不同的线程,而不是多次传递给同一个线程?

即 notify_one() 是什么意思:

1) notify one thread, no matter has it been already notified (but has not been woken up yet), or not. (* see note)
or
2) notify one thread, but only this one, which has not been notified yet.

(*) 注意!我不是在这里谈论场景“等待线程已经在过去的某个地方得到通知,被唤醒,做一些事情并再次进入 condvar.wait()” - 当然,在这种情况下,可以唤醒几个 notify_one() 例程同样的线程一遍又一遍。

我说的是另一个案例

notify_one() 已通知等待线程唤醒,但在此等待线程从内核调度程序接收到时隙并继续执行之前 - 另一个 notify_one() 已被再次调用。是否有可能第二个通知将再次传递到同一个线程,而它还没有从第一个通知中唤醒?

4

1 回答 1

7

notify_one调用以原子方式解除对一个线程的阻塞。这意味着当第二次调用它时,它不能解除阻塞同一个线程,因为它不再被阻塞。

这在标准的第 30.5/3 和 30.5.1/7 节中有所规定。

于 2013-02-26T09:51:18.443 回答