C++是否读取和写入了原子?

the*_*zer 79 c++ multithreading synchronization

我有两个线程,一个更新一个int,另一个读取它.这是一个统计值,其中读取和写入的顺序无关紧要.

我的问题是,我是否需要同步访问这个多字节值?或者,换句话说,写入的一部分可以完成并被中断,然后读取就会发生.

例如,假设值= 0x0000FFFF,其值递增为0x00010000.

是否有时间值看起来像0x0001FFFF,我应该担心?当然,类型越大,发生这种情况的可能性就越大.

我总是同步这些类型的访问,但很好奇社区的想法.

Ski*_*izz 63

男孩,真是个问题.答案是:

是的,不,嗯,这取决于

这一切都归结为系统的架构.在IA32上,正确对齐的地址将是原子操作.未对齐的写入可能是原子的,它取决于正在使用的缓存系统.如果内存位于单个L1缓存行中,则它是原子的,否则不是.CPU和RAM之间的总线宽度会影响原子性质:8086上正确对齐的16位写入是原子的,而8088上的相同写入不是因为8088只有8位总线而8086有16位总线.

此外,如果您正在使用C/C++,请不要忘记将共享值标记为volatile,否则优化器会认为该变量永远不会在您的某个线程中更新.

  • volatile线程在多线程程序中无用http://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming (21认同)
  • @IngeHenriksen:我不相信这个链接. (5认同)
  • 这个答案已经过时了。从 C++11 开始,对非 `std::atomic<int>` 的 int 进行非同步访问是一种数据竞争,并且是未定义的行为。所以目前的正确答案是肯定的**不**。 (3认同)

Ada*_*itz 47

起初人们可能认为本机大小的读取和写入是原子的,但是有许多问题要处理,包括处理器/核心之间的高速缓存一致性.在Windows上使用Interlocked*等原子操作,在Linux上使用等效操作.C++ 0x将有一个"原子"模板将它们包装在一个漂亮的跨平台接口中.目前,如果您使用的是平台抽象层,它可能会提供这些功能. ACE确实如此,请参阅类模板ACE_Atomic_Op.


gab*_*abr 11

如果您正在读/写4字节值并且它在内存中是DWORD对齐的并且您在I32架构上运行,那么读取和写入都是原子的.

  • 在 C++ 级别上情况并非如此。底层机器指令是原子性的,但允许编译器以破坏原子性的方式进行优化。 (4认同)
  • 英特尔架构软件开发人员手册中的哪些内容如下所述? (2认同)
  • @DanielTrebbien:也许可以看http://stackoverflow.com/questions/5002046/atomicity-in-c-myth-or-reality (2认同)

Ant*_*ams 8

是的,您需要同步访问.在C++ 0x中,它将是一个数据争用和未定义的行为.使用POSIX线程,它已经是未定义的行为.

实际上,如果数据类型大于本机字大小,则可能会得到错误的值.此外,由于优化移动读取和/或写入,另一个线程可能永远不会看到写入的值.


归档时间:

查看次数:

30671 次

最近记录:

8 年,8 月 前