Multithreading 为什么一个CPU写入的值不被另一个CPU看到?

Multithreading 为什么一个CPU写入的值不被另一个CPU看到?,multithreading,linux-kernel,memory-barriers,smp,Multithreading,Linux Kernel,Memory Barriers,Smp,抱歉,如果这是非常基本的。这是我正在做的事情的简化版本。我正在写一个内核模块。当它运行时,将有两个线程一个两个不同的物理CPU。我使用一个全局变量在这些线程之间进行特定的通信。奇怪的是,有时一个线程所写的内容被另一个线程所看不见。原因可能是什么 我怀疑这与内存障碍和缓存同步有关,所以我尝试在写入后使用smp_wmb(),但似乎没有帮助。据我所知,我不能显式地控制缓存同步。所以我有点困了 有什么想法吗 编辑:请明确说明说明是简化版本。我认为由于编译器优化,您正面临这个问题 您是否尝试过使用vola

抱歉,如果这是非常基本的。这是我正在做的事情的简化版本。我正在写一个内核模块。当它运行时,将有两个线程一个两个不同的物理CPU。我使用一个全局变量在这些线程之间进行特定的通信。奇怪的是,有时一个线程所写的内容被另一个线程所看不见。原因可能是什么

我怀疑这与内存障碍和缓存同步有关,所以我尝试在写入后使用smp_wmb(),但似乎没有帮助。据我所知,我不能显式地控制缓存同步。所以我有点困了

有什么想法吗


编辑:请明确说明说明是简化版本。

我认为由于编译器优化,您正面临这个问题

您是否尝试过使用
volatile
?我认为在你的情况下,
volatile


当对来自多个源(进程)的变量执行并发非同步操作时,应使用
volatile
关键字。如果变量被声明为volatile,那么所有进程将始终从其内存位置直接访问变量,而不是将变量复制到微处理器缓存中并从那里访问它

首先,你做错了。CPU之间的正确同步是非常复杂的,并且是特定于体系结构的问题。您应该使用一些现有的内核机制进行线程同步。除非您有特定的性能需求,否则只需使用旋转锁即可。然后,如果需要,您可以阅读更多关于不同同步机制的内容,并找到最适合您的工作负载的同步机制

为了更直接地回答您的问题,您可能会面临至少两个问题: 1.编译器对指令的重新排序通常由编译器屏障(即
barrier()
)负责。 2.CPU无序执行和缓存一致性通常由内存屏障负责


详细信息是特定于架构和用例的,但您没有提供我们可以分析的任何代码或架构详细信息。因此,您可能需要至少使用
barrier()
smp\u wmb()
smp\u rmb()
smp\u read\u barrier\u dependens()
。由于内核模块让我假设为C,您是否声明了变量volatile?@Gabeschen是的,我尝试过。遵循其他内核代码使用的模式。此外,除非你正在做一些非常不寻常的事情,否则写内存障碍应该在写之前。这个值传达了什么意思?如果您想要一个具体的答案,您可以提供一个或多个代码片段。如果您有两个物理CPU实现NUMA,这种行为在没有正确处理的情况下似乎非常合理,无论是在其他可能不会发生的架构上(还请注意,这不是不以正确方式做事的借口)。无论如何,不管是否为NUMA,您都应该使用volatile限定符。volatile限定符通常不会影响变量的值是在缓存中还是在内存中。它通常只影响变量的值是否临时保存在寄存器中。