4

如果我在没有任何时间间隔的情况下两次调用 std::condition_variable::notify_one() 会唤醒多少个等待线程,如下所示:

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

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

是否可以保证这些通知将被传递到不同的线程,而不是多次传递给同一个线程?

4

2 回答 2

4

§30.5.1.7:如果任何线程被阻塞等待 *this,则取消阻塞其中一个线程。

不能保证它是不同的线程,只是它是一个线程。在两次notify_one调用之间的时间里,第一次唤醒的同一个线程可能会notify_one被重新阻塞。

例如,在下面的示例中,不能保证线程 3 是否会唤醒(在此示例中忽略虚假唤醒)。

- thread 1:

1    condvar.notify_one();
- 3 and 4 could run here.
2    condvar.notify_one();

- thread 2:

3    condvar.wait(/*...*/);
4    condvar.wait(/*...*/);

- thread 3:

5    condvar.wait(/*...*/);
于 2013-02-26T08:07:10.403 回答
1

我认为这condvar_mutex是 condvar 的正确互斥锁。

不可能将两个通知传递到同一个线程。原因是您在持有 mutex 时notify_one调用了两次。因此,无论哪个线程先解锁,它都无法获取互斥锁,因此无法从. 如果不首先获取互斥锁,它甚至不能抛出异常。waitwait_for

由于它无法退出等待,因此它无法在第二个notify_one被调用之前回到服务员列表中。

因此,如果有那么多线程,您的代码最多可以解除 condvar 上阻塞的两个线程。如果数量较少,则附加通知无效。

于 2013-02-26T09:32:49.983 回答