Краткий и быстрый ответ : volatile
(почти) бесполезен для независимого от платформы многопоточного прикладного программирования.Он не обеспечивает никакой синхронизации, не создает заборов памяти и не обеспечивает порядок выполнения операций.Это не делает операции атомарными.Это не делает ваш код волшебным потокобезопасным.volatile
может быть самым непонятным средством во всем C ++.См. this , this и this для получения дополнительной информации о volatile
С другой стороны, volatile
имеет некоторое использование, котороеможет быть не так очевидно.Его можно использовать почти так же, как можно было бы использовать const
, чтобы помочь компилятору показать вам, где вы могли совершить ошибку при доступе к некоторому общему ресурсу незащищенным способом.Это использование обсуждается Александреску в этой статье .Тем не менее, это в основном использует систему типов C ++ таким образом, что часто рассматривается как ухищрение и может вызывать неопределенное поведение.
volatile
было специально предназначено для использования при взаимодействии с отображенным в память оборудованием, сигналомобработчики и инструкция машинного кода setjmp.Это делает volatile
непосредственно применимым к программированию на системном уровне, а не к нормальному программированию на уровне приложений.
Стандарт C ++ 2003 не говорит о том, что volatile
применяет любой тип семантики Acquire или Release к переменным.На самом деле, стандарт полностью ничего не говорит о многопоточности.Однако определенные платформы применяют семантику Acquire и Release к volatile
переменным.
[Обновление для C ++ 11]
Стандарт C ++ 11 теперь делает распознает многопоточность непосредственно в модели памяти и языке и предоставляет библиотечные средства для работы с ней независимо от платформы.Однако семантика volatile
все еще не изменилась.volatile
все еще не является механизмом синхронизации.Бьярн Страуструп говорит в TCPPPL4E следующее:
Не используйте volatile
, за исключением низкоуровневого кода, который напрямую связан с аппаратным обеспечением.
Не предполагайте, что volatile
имеет особое значениев модели памяти.Это не.Это не - как в некоторых более поздних языках - механизм синхронизации.Чтобы получить синхронизацию, используйте atomic
, mutex
или condition_variable
.
[/ End update]
Выше все относится к самому языку C ++,в соответствии со стандартом 2003 года (а теперь и стандартом 2011 года).Однако некоторые конкретные платформы добавляют дополнительную функциональность или ограничения к тому, что делает volatile
.Например, в MSVC 2010 (по крайней мере) семантика Acquire и Release do применяется к определенным операциям с volatile
переменными. Из MSDN :
При оптимизации компилятор должен поддерживать упорядочение среди ссылок на изменчивые объекты, а также ссылок на другие глобальные объекты.В частности,
Запись в энергозависимый объект (энергозависимая запись) имеет семантику Release;ссылка на глобальный или статический объект, который происходит до того, как запись в энергозависимый объект в последовательности команд произойдет до того, как энергозависимая запись в скомпилированном двоичном файле.
Чтение энергозависимого объекта (volatile read) имеет Acquireсемантика;ссылка на глобальный или статический объект, который происходит после чтения энергозависимой памяти в последовательности команд, будет происходить после этого энергозависимого чтения в скомпилированном двоичном файле.
Однако вы можете принять во внимание тот факт, чтоЕсли вы перейдете по вышеуказанной ссылке, в комментариях возникнут споры о том, применима ли в этом случае семантика приобретения / выпуска , на самом деле .