推定:
A. WIN32 での C++。
InterlockedIncrement()
B.およびを使用してインクリメントおよびデクリメントされる、適切にアラインされた揮発性整数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
}
この件については、多少の混乱があるようです。Windowsではレジスタサイズの読み取りがアトミックであることを理解しているので、このInterlockedXXX
機能は不要であると思います。
マット J.
わかりました、回答ありがとうございます。ところで、これは Visual C++ 2005 および 2008 です。
それが本当なら、InterlockedXXX
関数を使用して の値を読み取る必要があります_ServerState
。わかりやすくするためだけに、それを行う最善の方法は何ですか?
LONG x = InterlockedExchange(&_ServerState, _ServerState);
これには、値を変更するという副作用があります。本当にやりたいのは値を読み取ることだけです。_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);