Существует 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 или обертки.
Комментариев нет:
Отправить комментарий