假设我有一个随意的单字节变量。我认为几乎所有系统上的单字节操作都是原子的,但如果不是,请告诉我。现在,假设一个线程更新了这个变量。我应该期待/准备多长时间才能让此更新出现在其他线程中?我知道我可以将更新放在互斥锁/锁/障碍周围,以确保它在任何地方都同步,但我对此很好奇。等待时间可能会有所不同,具体取决于其他线程是否位于单独的处理器/内核上,并且可能取决于处理器类型。
我想知道这个是合乎逻辑的还是我误解了什么?
假设我有一个随意的单字节变量。我认为几乎所有系统上的单字节操作都是原子的,但如果不是,请告诉我。现在,假设一个线程更新了这个变量。我应该期待/准备多长时间才能让此更新出现在其他线程中?我知道我可以将更新放在互斥锁/锁/障碍周围,以确保它在任何地方都同步,但我对此很好奇。等待时间可能会有所不同,具体取决于其他线程是否位于单独的处理器/内核上,并且可能取决于处理器类型。
我想知道这个是合乎逻辑的还是我误解了什么?
只要您调用同步原语/内存屏障(例如pthread_mutex_lock
. 除此之外,除非您使用 C11 原子类型,否则不应假设任何同步。
在许多架构中,处理器不会刷新缓存,直到它必须为一些更需要的数据让路。
但是,如果线程共享内存空间,并且您只有一个内核,它们将能够“立即”从缓存中看到更新。如果它实际上是从 CPU 写入内存的。如果编译器决定将其保存在寄存器中,则可能不是这样,在这种情况下,您的线程都将拥有自己的“本地”和不正确的副本。
正如其他人所说,这是一个有趣的问题 - 但同步的正确答案是使用正确的同步原语!
在 MIPS 架构上,有一条同步指令用作跨内核的加载存储屏障,即发出同步之前的所有加载和存储都将在同步之后的任何加载和存储之前发生。不确定 x86 中是否有等效指令(假设是您正在使用的架构)。