По моему мнению, вы не должны ожидать слишком многого от volatile
. Чтобы проиллюстрировать это, посмотрите на пример из высоко оцененного ответа Нильса Пипенбринка .
Я бы сказал, его пример не подходит для volatile
. volatile
используется только для: предотвращения компилятора от полезных и желательных оптимизаций . Это не относится к потокобезопасности, атомарному доступу или даже к порядку памяти.
В этом примере:
void SendCommand (volatile MyHardwareGadget * gadget, int command, int data)
{
// wait while the gadget is busy:
while (gadget->isbusy)
{
// do nothing here.
}
// set data first:
gadget->data = data;
// writing the command starts the action:
gadget->command = command;
}
только gadget->data = data
перед gadget->command = command
гарантируется только в скомпилированном коде компилятором. Во время выполнения процессор все еще может переупорядочивать данные и назначение команд в соответствии с архитектурой процессора. Оборудование может получить неверные данные (предположим, гаджет сопоставлен с аппаратным вводом / выводом). Необходим барьер памяти между данными и назначением команд.
Исправлено в версии Steam путем отключения внутриигрового наложения таким образом: http://forums.steampowered.com/forums/showthread.php?t=3168263
Это было замаскировано тем фактом, что моя копия компакт-диска стала поврежденной, хотя при ее установке она часто зависала. Я купил копию Steam, и сбой продолжался, я недавно понял, что именно поэтому.