gpt4 book ai didi

c - InterlockedExchange 在 vmware 下失败,解决方法?

转载 作者:太空宇宙 更新时间:2023-11-03 23:33:16 24 4
gpt4 key购买 nike

一个非常简单的方法。两个线程。

volatile __int32 p=0;

一个线程(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 下却不行。

我是不是脑洞大开或...?

guest 操作系统:win2008 服务器

使用 Microsoft (R) C/C++ 优化编译器版本 15.00.30729.01 为 x64 编译的代码

主机:esxi 4.1

更新:

回复评论:是的会在0和1之间反弹, 但正如所写,线程 B 不会反弹,因为从 B 的角度来看,p 的值从不/或后方改变,它会反弹 10-20 次然后停止。

我只想在非常精确的时刻执行 A (ExecuteAVeryCPUIntesiveThing();) 中的代码块。

生产代码充满了更多线程和事件、互斥锁和锁,但事实仍然存在,如果我剥离并仅使用上面的代码,如果我在 guest 操作系统上生成大量 cpu、mm、io,我可以重现它.

最佳答案

这段代码是一场等待发生的线程竞赛。您可能是从 VMWare 获得它的,因为您只为虚拟机分配了一个处理器。

代码缺少的是确保线程 B 已经看到p 值更改的互锁。因此,如果线程 A 获得了一个 cpu 核心并继续运行了一段时间,而线程 B 被阻塞,等待一个量程运行,那么线程 A 可以多次将 p 设置为 0。线程 B 不会注意到这一点,因为它从来没有机会将 p 设置回 1。

您需要重新考虑您的锁设计。这个问题不仅限于 VMWare,它也可能在普通机器上出错,只是可能性要小得多。它每月出错一次,或多或少,无法调试。这是一种经典的生产者/消费者场景,您可以使用线程安全队列解决这一问题。

关于c - InterlockedExchange 在 vmware 下失败,解决方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10383022/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com