一个非常简单的方法。两条线。
volatile __int32 p=0;
一根线 (A) 只使用
while(1){
ExecuteAVeryCPUIntesiveThing();
InterlockedExchange(&p, 0);
}
另一个线程 (B) 使用
while(1){
if(0==InterlockedCompareExchange(&p,0,0))
InterlockedExchange(&p, 1);
}
如果有人试图在压力下的系统下记录这一点。(大量内存交换、io、socket、cpu 峰值..)来自 A 的值不会传播到 B。
在 A 中,p 的值似乎为 0。但从 B 的角度来看,p 停留在 1。在我的世界中,当 A 将值设置为 0 时,B 应该检测并将值设置为 0。在实际硬件上,它的工作原理就是这样但在 esxi 上运行时不会。
这似乎在真实硬件和某些虚拟系统下工作正常,但在 vmware 下不行。
我是不是做错了,还是……?
操作系统来宾:win2008服务器
使用 Microsoft (R) C/C++ Optimizing Compiler Version 15.00.30729.01 for x64 编译的代码
主机:esxi 4.1
更新:
对评论的回应:是的,它会在 0 和 1 之间反弹,但正如所写的,线程 B 不会反弹,因为从 p 的值永远/或在 B 的角度发生变化,它会反弹 10-20 次然后停止。
我只想在非常精确的时刻执行 A ( ExecuteAVeryCPUIntesiveThing();) 中的代码块。
生产代码充满了更多的线程和事件、互斥锁和锁,但事实仍然存在,如果我剥离并只使用上面的代码,如果我在来宾操作系统上生成大量 cpu、mm、io,我可以重现它。