Комментарии 3
Забавно, что в статье про data race и undefined behavior один из примеров сам содержит UB :) В calculate() результат суммы от 1 до 1 000 000 хранится в int. Правильная сумма там 500000500000, что сильно больше INT_MAX. В итоге происходит signed integer overflow, а в C++ это undefined behavior. То есть пример со std::async формально уже некорректен независимо от многопоточности. Достаточно заменить result на std::int64_t или long long
В разделе про std::condition_variable сейчас стоит пример со std::async, поэтому описанных ниже ready, wait и notify_one в коде нет. В примере с условной переменной полезно показать и случай, когда производитель успел раньше потребителя: notify_one не сохраняет уведомление для будущего ожидания. Сохраняется само состояние ready, которое читают и меняют под одним мьютексом; ожидание с предикатом сначала проверит его и при ready == true вообще не заснёт. Это следует из описания notify_one и wait с предикатом в проекте стандарта: https://eel.is/c++draft/thread.condition.condvar — уведомление будит уже ожидающий поток, а проверка условия выполняется перед wait.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Один счётчик, десять потоков и неправильный результат: разбираемся в многопоточности C++