Здравствуйте, 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 будет вызвана дважды для одного и того же итератора в одном из этих случайных потоков, то это состояние гонки.
Здравствуйте, B0FEE664, Вы писали:
BFE>>>Поэтому я не вижу никакого прямого способа использования этого примитива, кроме как превратив CV в что-то более логичное, например в объект Event (Событие).
N>>Именно что напрямую и используется. Сделать Event на её основе, конечно, можно, но не подходит в заметной части случаев, и излишне в большинстве остальных.
BFE>Разве есть что-то такое, что можно сделать на CV и нельзя на Event?
Я не сказал "нельзя", я сказал "не подходит"
В смысле, будет сильно неудобно — в рамках того подхода, в котором используются CV.
Насколько "нельзя", я не в курсе.
BFE>Что же касается излишеств, то экономить на спичках в большинстве случаев не следует.
Пока что вы действуете чисто по вкусовщине "мне не нравятся CV, я их не хочу понимать, все бегом на Event". Я вообще-то не собирался это глубоко обсуждать, но если уж идём в эту сторону...
покажите такой же thread pool, как я постил, на Event, и расскажите детально, почему он работает и почему он надёжно работает. Хотя лучше с этим куда-то за пределы субфорума C++. Например, в "Алгоритмы".
Никто не говорит, что подход с CV единственный или заведомо идеальный, но если не видно массового перехода на другой подход, то наверняка у него не столь фатальны отрицательные стороны, как вам кажется.
(Это я не вспоминаю, что в рамках стандарта C++ у нас пока в принципе нет альтернативы.)
N>>Оптимизировав логику шедулера, можно сократить частоту таких левых пробуждений, но свести до нуля — не получается. А ещё есть случаи старта новых задач в пул, и с ними надо тоже синхронизироваться.
BFE>Я не верю, что задача является неразрешимой.
Над этой темой думают сотни учёных в мире. Если с середины 60-х ничего не придумали, то, наверно, это не так просто, как вам кажется.