То, что вы знаете, ложно.Volatile - это , а не , используемый для синхронизации доступа к памяти между потоками, применения любых видов ограждений памяти или чего-либо подобного.Операции с volatile
памятью не являются атомарными, и они не гарантированно выполняются в каком-либо определенном порядке.volatile
является одним из самых неправильно понятых средств на всем языке.« Volatile практически бесполезно для многопоточного программирования. »
Для чего используется volatile
, это взаимодействие с отображенным в память оборудованием, обработчиками сигналов и инструкцией машинного кода setjmp
.
Он также может быть использован аналогично тому, как const
, и именно так Александреску использует его в этой статье .Но не заблуждайтесь.volatile
не делает ваш код магически безопасным.Используемый таким особым образом, это просто инструмент, который может помочь компилятору сообщить вам, где вы могли ошибиться.Все еще зависит от вас, чтобы исправить ваши ошибки, и volatile
не играет никакой роли в исправлении этих ошибок.
РЕДАКТИРОВАТЬ: Я постараюсь немного пояснить, что я простоsaid.
Предположим, у вас есть класс с указателем на что-то, что не может изменить .Вы можете сделать указатель константным:
class MyGizmo
{
public:
const Foo* foo_;
};
Что const
действительно для вас здесь делает?Это ничего не делает с памятью.Это не похоже на вкладку защиты от записи на старой дискете.Сама память по-прежнему доступна для записи.Вы просто не можете писать в него через указатель foo_
.Так что const
- это просто способ дать компилятору еще один способ сообщить вам, когда вы можете что-то испортить.Если вы напишите этот код:
gizmo.foo_->bar_ = 42;
... компилятор не допустит этого, потому что он помечен const
.Очевидно, что вы можете обойти это, используя const_cast
, чтобы отбросить const
-несс, но если вам нужно убедиться, что это плохая идея, тогда вам не помогут.:)
Александреску использует volatile
точно так же.Он ничего не делает для того, чтобы сделать память как-то «поточно-безопасной» , каким-либо образом .Он дает компилятору еще один способ сообщить вам, когда вы, возможно, облажались.Вы помечаете вещи, которые вы сделали действительно «поточно-ориентированными» (благодаря использованию реальных объектов синхронизации, таких как мьютексы или семафоры), как volatile
.Тогда компилятор не позволит вам использовать их в не volatile
контексте.Выдает ошибку компилятора, о которой вам нужно подумать и исправитьВы могли бы снова обойти это, отбрасывая volatile
-несс используя const_cast
, но это так же, как Зло, как отбрасывание const
-нес.1050 * как инструмент для написания многопоточных приложений (редактируйте :), пока вы действительно не будете знать, что вы делаете и почему.Это имеет некоторое преимущество, но не в том, как думает большинство людей, и если вы используете его неправильно, вы можете писать опасно опасные приложения.