Re[3]: C++11: Синхронизация - Условные переменные и ложные п
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 21.03.19 21:29
Оценка:
Здравствуйте, uzhas, Вы писали:

U>2) из-за того, что в void update не лочит мьютекс мы имеем race, из-за которого cv.wait(l) зависнет навечно, хотя ready_flag будет равен true. очень важно понимать, насколько мощен wait:

U>этот метод одновременно уходит в ожидание и разлочивает мьютекс (транзакционно). это гарантирует, что при правильном использовании (а не как в этом примере) cv, метод notify не уйдет в пустоту. гарантирует, что условие в while не может измениться, пока мы не провалимся в wait. поэтому менять данные, которые могут изменять condition, надо строго под мьютексом.

Нет. И такое изменение допустимо (см. ниже), и notify за пределами владения мьютексом разрешён во многих подобных реализациях (включая pthreads), и часто даже рекомендуется — за счёт того, что он не вызывает дополнительных переключений (когда задача, получившая нотификацию, пробуждается и тут же засыпает снова на ожидании мьютекса).

Пример Кодта плох не тем, что он мог бы не работать — он работает. Пример плох таки тем, что смешиваются два разных подхода — защита произвольных данных (в общем случае не пригодных к атомарному изменению) мьютексом — как полагается для этого механизма, и игр с interlocked exchange, которые тут требуют дополнительного объяснения — в частности, почему они вообще работают, а тут уже надо углубляться, что InterlockedExchange() содержит в себе полный барьер памяти, который в случае мьютекса реализуется собственно суммой входа в мьютекс и выхода из него.
По-нормальному надо было бы нарисовать что-то вроде кольцевого буфера с head, tail и length — это банальный избитый пример, но он показал бы основы проблемы. А уже после этого пытаться подключать внелоковые атомики.
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.