非常に単純なアプローチ。2 つのスレッド。
volatile __int32 p=0;
1本糸(A)のみ使用
while(1){
ExecuteAVeryCPUIntesiveThing();
InterlockedExchange(&p, 0);
}
もう一方のスレッド (B) は
while(1){
if(0==InterlockedCompareExchange(&p,0,0))
InterlockedExchange(&p, 1);
}
ストレス下のシステムでこれをログに記録しようとすると。(多くのメモリスワップ、io、ソケット、CPU スパイク..) A からの値は B に伝播されません。
A では、p の値は 0 のように見えます。しかし、B の観点から見ると、p は 1 に固定されています。私の世界では、A が値を 0 に設定すると、B は値を検出して 0 に設定する必要があります。実際のハードウェアでは、これはそのように機能します。 esxiで実行しているときはそうではありません。
これは、実際のハードウェアと一部の仮想システムでは正常に機能するようですが、vmware では機能しないようです。
私はマインドスリップをしましたか...?
OS ゲスト: win2008 サーバー
Microsoft (R) C/C++ Optimizing Compiler バージョン 15.00.30729.01 for x64 でコンパイルされたコード
ホスト: esxi 4.1
アップデート:
コメントへの応答: はい、0 と 1 の間でバウンスしますが、書かれているように、スレッド B はバウンスしません。これは、p からの値が B の視点で決して/またはまったく変化しないためです。10-20 回バウンスしてから停止します。
A ( ExecuteAVeryCPUIntesiveThing();) のコード ブロックを非常に正確なタイミングでのみ実行したいと考えています。
実稼働コードは、より多くのスレッドとイベント、ミューテックスとロックでいっぱいですが、事実は残ります。ゲスト OS で多くの cpu、mm、io を生成すると、上記のコードを削除して使用するだけで再現できます。