Глядя на несколько видео и пример документации , мы разблокируем мьютекс перед тем, как вызовет notify_all()
.Будет ли лучше вместо этого вызывать его после?
Общий способ:
Внутри потока уведомлений:
//prepare data for several worker-threads;
//and now, awaken the threads:
std::unique_lock<std::mutex> lock2(sharedMutex);
_threadsCanAwaken = true;
lock2.unlock();
_conditionVar.notify_all(); //awaken all the worker threads;
//wait until all threads completed;
//cleanup:
_threadsCanAwaken = false;
//prepare new batches once again, etc, etc
Внутри одного израбочие потоки:
while(true){
// wait for the next batch:
std::unique_lock<std::mutex> lock1(sharedMutex);
_conditionVar.wait(lock1, [](){return _threadsCanAwaken});
lock1.unlock(); //let sibling worker-threads work on their part as well
//perform the final task
//signal the notifier that one more thread has completed;
//loop back and wait until the next task
}
Обратите внимание, как разблокируется lock2
до того, как мы уведомим переменную условия - нужно ли вместо этого разблокировать после notify_all()
?
Редактировать
Из моего комментария ниже: Меня беспокоит то, что, если потребитель очень быстр.Потребитель внезапно просыпается, видит, что мьютекс разблокирован, завершает задачу и возвращается к началу времени.Теперь медленно работающий источник наконец вызывает notify_all (), заставляя потребителя зацикливаться еще раз.