一个变量只被一个线程读取,被另一个线程读取和写入,是否需要同步?

Does a variable only read by one thread, read and written by another, need synchronization?

动机:

我只是在学习多线程的基础知识,还没有接近完成它们,但我想在我的学习之旅的早期提出一个问题,以指导我找到与我正在工作的项目最相关的主题上。

主要:

一个。如果一个进程有两个线程,一个编辑一组变量,另一个只读取所述变量并且从不编辑它们的值;那么我们是否需要某种同步来保证读取线程读取值的有效性?

b。 OS 调度这两个线程是否有可能导致读取线程在写入线程写入同一内​​存位置的同时读取内存位置中的变量,或者这只是一个hardware/bus 永远不会允许这种情况发生,软件设计师永远不应该关心这种情况?如果变量是一个大结构而不是一个小的 int 或 char 怎么办?

a. If a process has two threads, one that edits a set of variables, the other only reads said variables and never edits their values; Then do we need any sort of synchronization for guaranteeing the validity of the read values by the reading thread?

一般来说,。否则,编辑该值的线程只能在本地更改该值,这样其他线程将永远看不到该值的更改。这可能是因为编译器(可以使用 寄存器 到 read/store 变量)但也因为硬件(关于 缓存一致性 目标平台上使用的机制)。通常,原子变量内存屏障用于执行此类同步。

b. Is it possible for the OS scheduling these two threads to cause the reading-thread to read a variable in a memory location in the exact same moment while the writing-thread is writing into the same memory location, or that's just a hardware/bus situation will never be allowed happen and a software designer should never care about that? What if the variable is a large struct instead of a little int or char?

一般来说,不能保证访问是自动完成的。从理论上讲,两个执行一个线程的内核可以同时 load/store 同一个变量(但实际上通常不会)。它非常依赖于目标平台。

对于具有(一致的)缓存的处理器(即所有现代主流处理器)缓存行(即通常为 64 或 128 字节的块)对隐式有巨大影响线程之间的同步。这是一个复杂的主题,但您可以先阅读更多有关 cache coherence 的内容,以了解内存层次结构在现代平台上的工作方式。 缓存一致性协议防止两个 load/store 在同一缓存行中完全同时完成。如果变量跨越多个缓存行,则没有保护。

在广泛使用的 x86/x86-64 平台上,原始类型 <= 8 字节的变量 可以 进行原子修改(因为总线以及 DRAM 和缓存)假设地址正确对齐(它不跨越缓存行)。但是,这并不意味着所有此类访问都是原子的。您需要将此指定给 compiler/interpreter/etc。所以它 produces/executes 正确的指令。请注意,还有 16 字节原子的扩展。还有一个指令集扩展,用于支持 事务内存 。对于更广泛的类型(或可能是复合类型),您可能需要 lockatomic state 来控制访问目标变量的原子性。