【问题标题】:Is the c++ operator |= atomic with a multicore processor?c++ 运算符 |= 是多核处理器的原子吗?
【发布时间】:2015-05-19 21:09:47
【问题描述】:

我目前正在与另一位开发人员进行辩论,他向我保证以下 c++ 语句是原子的:

x |= 0x1; // x is shared by multiple threads

在发布模式下使用 VC++11 编译,生成以下程序集:

01121270  or          dword ptr ds:[1124430h],1

另一位开发人员说位操作是原子的,因此是线程安全的。我使用英特尔 i7 处理器的经验并非如此。

我认为对于多核处理器,任何共享内存写入都是不安全的,因为有单独的处理器缓存。但经过更多研究后,似乎 x86 处理器提供了一些与处理器/内核之间的内存操作顺序相关的保证,这表明它应该是安全的......再次,这并不根据我的经验,似乎是这样。

由于我对这类事情没有权威的了解,我很难提出自己的观点,甚至很难确信自己是对的。

【问题讨论】:

  • 这只是平台相关的,不是吗?我认为您应该指定您的平台。
  • 某些编译器可能会在某些架构上生成线程安全代码,但不能保证。使用std::atomic<int> 也没有缺点,它有一个operator|=,保证是原子的,所以你应该这样做。
  • 我很确定在 x86 架构上需要 lock 指令前缀,以确保在多个处理器/内核的情况下的原子性。 IE。它必须是lock or dword ptr ds:[11224430h],1。但我手边没有参考资料。如果你use std::atomic<int>,它会编译成什么?
  • 对不起,我指的是x86平台

标签: c++ multithreading concurrency multiprocessing atomic


【解决方案1】:

不,它绝对不能保证是原子的。是否使用不可中断指令(序列)实现取决于编译器和平台。但从标准的角度来看,它不是原子的;因此,如果一个线程执行 x |= 0x1; 并且另一个线程访问 x 之间没有同步点,这是未定义的行为(数据竞争)。

来自 C++11 的支持引用:

1.10/5:

该库定义了许多原子操作(第 29 条)和互斥锁操作(第 30 条) 特别标识为同步操作。 ...

第 29 条介绍了std::atomic 和相关功能。它没有将基本类型指定为原子。

1.10/21:

如果一个程序在不同的线程中包含两个冲突的动作,则该程序的执行包含一个数据竞争, 至少其中一个不是原子的,也没有发生在另一个之前。任何此类数据竞争都会导致 未定义的行为。 ...

【讨论】:

  • 谢谢,我有一种感觉,但没有信心断言它。
  • @RobertSmith 作为记录,“冲突动作”和“发生在之前”在 1.10 中也有精确定义,但我不想复制一半的章节。
猜你喜欢
  • 2017-06-14
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
相关资源
最近更新 更多