如果我在没有任何时间间隔的情况下两次调用 std::condition_variable::notify_one() 会唤醒多少个等待线程,如下所示:
{
std::unique_lock<std::mutex> lock(condvar_mutex);
condvar.notify_one();
condvar.notify_one();
}
是否可以保证这些通知将被传递到不同的线程,而不是多次传递给同一个线程?
如果我在没有任何时间间隔的情况下两次调用 std::condition_variable::notify_one() 会唤醒多少个等待线程,如下所示:
{
std::unique_lock<std::mutex> lock(condvar_mutex);
condvar.notify_one();
condvar.notify_one();
}
是否可以保证这些通知将被传递到不同的线程,而不是多次传递给同一个线程?
§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(/*...*/);
我认为这condvar_mutex
是 condvar 的正确互斥锁。
不可能将两个通知传递到同一个线程。原因是您在持有 mutex 时notify_one
调用了两次。因此,无论哪个线程先解锁,它都无法获取互斥锁,因此无法从. 如果不首先获取互斥锁,它甚至不能抛出异常。wait
wait_for
由于它无法退出等待,因此它无法在第二个notify_one
被调用之前回到服务员列表中。
因此,如果有那么多线程,您的代码最多可以解除 condvar 上阻塞的两个线程。如果数量较少,则附加通知无效。