Короткий ответ : Не используйте volatile для гарантии атомарности.
Длинный ответ Можно подумать, что поскольку процессоры обрабатывают слова в одной инструкции, простое словооперации по своей сути потокобезопасны.Идея использования volatile
состоит в том, чтобы гарантировать, что компилятор не делает никаких предположений о значении, содержащемся в общей переменной.
На современных многопроцессорных компьютерах это предположение неверно.Учитывая, что разные ядра процессора обычно имеют свой собственный кэш, могут возникнуть ситуации, когда операции чтения и записи в основную память переупорядочиваются, и ваш код в конечном итоге не работает должным образом.
По этой причине всегда использовать блокировки, такие как мьютексы или критические секции, при доступе к памяти, разделяемой между потоками.Они на удивление дешевы, когда нет разногласий (обычно нет необходимости совершать системный вызов), и они будут делать правильные вещи.
Как правило, они предотвращают неупорядоченные операции чтения и записи, вызывая инструкцию Data Memory Barrier (DMB on ARM), которая гарантирует, что чтение и запись происходят в правильном порядке.Смотрите здесь для получения более подробной информации.
Другая проблема с volatile
заключается в том, что он не даст компилятору оптимизировать, даже когда это совершенно нормально.