在 x86-64 上被认为是原子的 C 程序中分配一个指针

use*_*645 7 c multithreading gcc x86-64 atomic

https://www.gnu.org/software/libc/manual/html_node/Atomic-Types.html#Atomic-Types说 -在实践中,你可以假设 int 是原子的。你也可以假设指针类型是原子的;那很方便。这两个假设在 GNU C 库支持的所有机器上和我们知道的所有 POSIX 系统上都是正确的。

我的问题是,对于使用 gcc m64 标志编译的 C 程序,是否可以将指针分配视为 x86_64 架构上的原子分配。操作系统为 64 位 Linux,CPU 为 Intel(R) Xeon(R) CPU D-1548。一个线程将设置一个指针,另一个线程将访问该指针。只有一个写入线程和一个读取线程。Reader 应该获取指针的先前值或最新值,并且两者之间没有垃圾值。

如果它不被认为是原子的,请让我知道我如何使用 gcc 原子内置函数或者像 __sync_synchronize 这样的内存屏障来实现相同的效果而不使用锁。只对 C 解决方案感兴趣,对 C++ 不感兴趣。谢谢!

Max*_*kin 6

请记住,仅原子性不足以在线程之间进行通信。没有什么可以阻止编译器CPU使用该“原子”存储重新排序先前/后续加载和存储指令。在过去,人们过去常常volatile阻止这种重新排序,但这从未打算用于线程,并且不提供指定更少或更多限制性内存顺序的方法(请参阅“与volatile”的关系)。

您应该使用 C11 原子,因为它们保证原子性和内存顺序。

  • 通常想要避免“#include <stdatomic.h>”和“_Atomic”的人希望这样做,因为他们认为效率较低。`memory_order_relaxed` 通常会编译为与使用 `volatile` 和/或 ` asm("" ::: "memory")` 屏障获得的 asm 相同的 asm,以确保安全(在特定实现上不可移植),而无需使用 ` _原子`。相关:[何时在多线程中使用 volatile?](/sf/answers/4097458291/) - 正如你所说,永远不会。 (3认同)