2013-02-26 3 views
2

Сколько ожидающий поток проснётся, если я позвоню станд :: condition_variable :: notify_one() дважды без какого-либо временного интервала, например:станд :: condition_variable :: notify_one() вызывается дважды

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

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

ли есть ли гарантия, что эти уведомления будут доставлены в разные потоки, а не один и тот же поток несколько раз?

+0

Вы в основном спрашиваете, можно ли еще раз уведомить уведомляемый поток (и заблокирован на мьютексе), поскольку он больше не ждет на 'cond_var' и скорее блокирован на' condvar_mutex'? –

+0

Извините. Этот вопрос был слишком неясным. Я перефразировал его здесь: http://stackoverflow.com/questions/15085823/stdcondition-variablenotify-one-called-several-times-without-context-switc и помечен для удаления. – Vasily

ответ

4

§30.5.1.7: Если любые потоки заблокированы в ожидании * этого, разблокирует один из этих тем.

Там нет никакой гарантии, что это разные темы, так что это один нить. В течение времени между двумя вызовами 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(/*...*/); 
+0

Что произойдет, если я помещу как notify_one() под тем же мьютексом, чтобы предотвратить ваш сценарий? – Vasily

+0

Возможно, я задал неправильный вопрос. На самом деле, мне было интересно - есть ли возможность просыпаться только один condvar.wait (...) после вызова notify_one() дважды. Итак, давайте предположим, что в вашем примере нет нити 3. Возможно ли, что второй поток будет извещен только один раз и будет заблокирован во втором condvar.wait()? – Vasily

0

Я предполагаю, что condvar_mutex является правильным мьютекс для condvar.

Невозможно, чтобы оба уведомления доставлялись в одну и ту же резьбу. Причина в том, что вы звоните notify_one дважды , удерживая мьютексы. Итак, какая бы ни была разблокирована нить, сначала невозможно получить мьютекс, поэтому он не может вернуться с wait. Он не может даже выбросить исключение из wait_for без предварительного получения мьютекса.

Поскольку он не может выбраться из своего ожидания, он не сможет вернуться к списку официантов до того, как будет вызван второй notify_one.

Итак, ваш код разблокирует до двух потоков, заблокированных на condvar, если их так много. Если их меньше, то дополнительные уведомления не влияют.

+0

Извините. Похоже, мой вопрос был слишком неясным. Я перефразировал его и снова спросил здесь: [link] (http://stackoverflow.com/questions/15085823/stdcondition-variablenotify-one-called-several-times-without-context-switc) – Vasily

Смежные вопросы