Здравствуйте, watchmaker, Вы писали:
BFE>>Это описание выглядит как описание типичной ошибки race condition: два независимых события 'пробудить очередь' и 'отдать-захватить мьютекс' не синхронизированы.
W>Конкретно в этом примере нет гонки с пробуждением. Он же позвал notify_one внутри захвата мьютекса. Ядро в ответ на вызов notify_one тут же будит поток (который попадает в планировщик), и лишь потом отпускает мьютекс. Что это тогда, если не самая лучшая синхронизация?
Уточню: гонка тут не со стороны приведённого кода, а со стороны системы.
W>Если другая проблема: потоки могут тупить по сотне разных причин. То им процессора не достанется, или достанется, но их другой поток тут же вытеснит, то page fault случится. В результате задание из очереди получает более расторопный поток (и это хорошо). И по большому счёту эта ситуация эквивалентна другой ситуации, в которой нет никаких условных переменных и сигналов пробуждения, а просто есть два потока-исполнителя стартующих одновременно и единственное задание в очереди. Никто же не называет гонкой ситуацию, что задание может достаться одному исполнителю или другому:
W>W>std::vector<int> v = {{1}};
W>std::for_each(std::execution::parallel_policy, begin(v), end(v), fn);
W>
W>— не гонка, что fn будет вызван в случайном потоке из пула.
Если fn будет вызвана дважды для одного и того же итератора в одном из этих случайных потоков, то это состояние гонки.