Страницы

Поиск по вопросам

среда, 27 ноября 2019 г.

Будет ли состояние гонок, если один поток меняет переменную типа bool, а другой читает из неё?


Существует 2 потока, один из которых читает данные из переменной типа bool, а другой
может менять её значение. 
Являются ли эти две операции атомарными по отношению друг к другу?
А если нет, то подскажите, пожалуйста, какую-нибудь стандартную обертку, чтобы сделать
монопольный доступ к этой переменной.
Разумеется, можно сделать метод доступа, который бы синхронизировал доступ, но мне
не хочется изобретать велосипед.
Используются ОС Unix    


Ответы

Ответ 1



Операции не могут быть атомарными по отношению друг к другу, они либо атомарные, либо неатомарные. Собственно, если переформулировать ваш вопрос как "Являются ли read и write для bool атомарными?", то на него уже можно попытаться ответить. А ответ достаточно простой - нет, не являются. Атомарность этих операций нигде не специфицирована, поскольку она зависит от архитектуры машины, на которой выполняется скомпилированный код. Так, чтение bool в unaligned случае вполне может привести к генерированию 2+ инструкций. Вторая проблема - когерентность кэшей. Операция должна быть инвариантной относительно всех кэшей процессора, а значит потенциально она перестает быть атомарной. Теперь чуть ближе к практике. В новом стандарте C++11 для гарантированной атомарности операций над интегральными типами следует использовать std::atomic_bool. Если используется boost, то лично я бы (не знаком с вашей задачей и тыкаю пальцем в небо) организовал сихронизацию при работе с переменной типа bool с помощью boost::condition_variable. Возможно, вам подойдет использование (специфично для WinAPI) Interlocked функций для доступа к переменной или же, например, какой-нибудь классический механизм синхронизации типа Critical Section. ... Подробнее по поводу атомарности операций read / write, их архитектурозависимости и про Microsoft-specific обещания касательно применения volatile можно почитать здесь и здесь.

Ответ 2



Самый типичный случай гонки. Просто так атомарными эти операции не будут. Для синхронизации надо использовать мьютексы или семафоры. Конкретная реализация зависит от операционной системы, а также от того, как Вы организуете многопоточность: используя низкоуровневые API или обертки.

Комментариев нет:

Отправить комментарий