首页 > 解决方案 > 跨线程读取无符号整数时,c++ 位是否自动切换?

问题描述

在 mac、pc 和 unix 上的 C++ 中:如果我在一个线程(写入线程)上写入无符号整数或 Ipp32us 并从另一个线程(读取线程)读取无符号整数,则读取线程是否读取没有故障,即使写线程正在写。我想知道这些位是否是原子切换的。谢谢

标签: c++multithreading

解决方案


按照标准,对于非原子类型,没有任何保证。在实践中,它通常取决于底层硬件和相关数据类型的对齐方式;例如,如果 64 位写入在硬件上实现为一对 32 位写入,那么您可以看到损坏的值(旧值的一半,新值的一半)。如果硬件将它们实现为真正的 64 位写入,那么您可能是安全的,但这不是可以指望的。

请记住,“写入”可能会在多个阶段被撕裂,例如编译器实际上可能会为每一半生成单独的移动到内存指令(因此即使在单个内核上,也可以在写入的两半之间安排另一个线程),或者它可能将其编写为一条指令,但处理器在内部将其实现为一对写入(以任何一种顺序,甚至程序集都不会告诉您顺序;x86 之类的体系结构似乎执行 CISC 指令,但实际上将它们转换为完全不同的内部 RISC 指令集),或者处理器可能将其实现为单次写入,但如果存储跨越高速缓存行并且系统的内存排序较弱,它可能很容易被其他处理器请求它的时间,等等。

重点是,如果您想要原子写入和读取,请实际使用C++11std::atomic类型。没有它,即使它可以工作,也只是意味着它可以在那个编译器上工作,在那个硬件上工作,并且对可移植性一无所知。


推荐阅读