c++ - 在 x86 中增加一个整数原子吗?

标签 c++ c gcc x86 x86-64

在多核 x86 机器上,假设在 core1 上执行的线程递增一个整数变量 a,同时 core 2 上的线程也递增它。假设 a 的初始值为 0,那么它最终会不会是 2 呢?或者它可能有其他值(value)?假设 a 被声明为 volatile 并且我们没有使用原子变量(例如 C++ 的 atomic<> 和 gcc 中内置的原子操作)。

如果在这种情况下 a 的值确实总是 2,这是否意味着 x86-64 中的 long int 也将具有相同的属性,即就是说,a到底总是2?

最佳答案

X86 上的增量内存机器指令只有在您使用 LOCK 前缀时才是原子的。

C 和 C++ 中的

x++ 没有原子行为。如果您执行解锁增量,由于处理器正在读取和写入 X 的竞争,如果两个单独的处理器尝试增量,您最终可能只看到一个增量或两者都被看到(第二个处理器可能已经读取了初始值,增量它,并在第一次写回结果后将其写回)。

我相信 C++11 提供了原子增量,并且大多数供应商编译器都有一种惯用的方式来导致某些内置整数类型(通常是 int 和 long)的原子增量;请参阅您的编译器引用手册。

如果你想增加一个“大值”(比如一个多精度整数),你需要使用一些标准的锁定机制,比如信号量。

请注意,您还需要担心原子读取。在 x86 上,读取 32 或 64 位值恰好是原子的,如果它是 64 位字对齐的。 “大值(value)”并非如此。再次,您将需要一些标准锁。

关于c++ - 在 x86 中增加一个整数原子吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10503737/

相关文章:

c++ - 顶行右对齐的 MFC 工具栏

gcc - 如何使用 distcc 仅远程预处理和编译所有内容?

c - 使用自定义 __start 的 GCC/LD 的异常输出

c++ - 如何在 C++ 中使用迭代器进行打印?

c++ - inFile 应该放在 -o 标志之前还是之后?

c - 数组指针和返回类型

c - 从没有强制转换的整数生成指针... DS1307、RTC、BCD

c - gcc gdb building - "lvalue required as increment operand"on *((void **)__o->next_free)++ = ((void *)datum);

c++ - 列出 OpenCV 支持的文件扩展名

c - 如何使用 NodeMCU 和 enduser_setup 捕获用户的 MAC 地址?