std :: condition_variable :: notify_one () вызывается несколько раз без переключения контекста

Сколько ожидающих потоков проснется в этом примере:

1-й поток:

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

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

2-й поток:

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

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

3-я нить (так же, как 2-й):

{
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 (). Возможно ли, что второе уведомление будет доставлено в тот же поток снова, пока оно еще не проснулось от первого уведомления?

0

Решение

notify_one вызов атомарно разблокирует один поток. Это означает, что при повторном вызове он не может разблокировать тот же поток, поскольку он больше не блокируется.

Это указано в стандарте в разделах 30.5 / 3 и 30.5.1 / 7.

4

Другие решения

Других решений пока нет …