Предположим:
а. С++ под WIN32.
В. Правильно выровненное неизменяемое целое число увеличивается и уменьшается с помощью InterlockedIncrement()
и InterlockedDecrement()
.
__declspec (align(8)) volatile LONG _ServerState = 0;
Если я хочу просто прочитать _ServerState, мне нужно прочитать переменную с помощью функции InterlockedXXX
?
Например, я видел код, например:
LONG x = InterlockedExchange(&_ServerState, _ServerState);
и
LONG x = InterlockedCompareExchange(&_ServerState, _ServerState, _ServerState);
Цель состоит в том, чтобы просто прочитать текущее значение _ServerState
.
Не могу ли я просто сказать:
if (_ServerState == some value)
{
// blah blah blah
}
Кажется, существует некоторая путаница WRT этой темы. Я понимаю, что чтение в регистровом формате является атомарным в Windows, поэтому я бы предположил, что функция InterlockedXXX
не нужна.
Мэтт Дж.
Хорошо, спасибо за ответы. Кстати, это Visual С++ 2005 и 2008.
Если это правда, я должен использовать функцию InterlockedXXX
для чтения значения _ServerState
, даже если только для ясности, что лучший способ сделать это?
LONG x = InterlockedExchange(&_ServerState, _ServerState);
Это имеет побочный эффект изменения значения, когда все, что я действительно хочу сделать, это прочитать его. Не только это, но есть вероятность, что я могу reset флаг ошибочного значения, если есть переключатель контекста, поскольку значение _ServerState
помещается в стек при подготовке вызова InterlockedExchange()
.
LONG x = InterlockedCompareExchange(&_ServerState, _ServerState, _ServerState);
Я взял это из примера, который я видел на MSDN.
См. http://msdn.microsoft.com/en-us/library/ms686355(VS.85).aspx
Все, что мне нужно, это что-то вроде строк:
lock mov eax, [_ServerState]
В любом случае точка, которая, как я считала, была ясной, заключается в обеспечении поточного доступа к флагом без возникновения накладных расходов критического раздела. Я видел, как LONG использовали этот путь через семейство функций InterlockedXXX()
, поэтому мой вопрос.
Хорошо, мы думаем, что хорошим решением этой проблемы является чтение текущего значения:
LONG Cur = InterlockedCompareExchange(&_ServerState, 0, 0);