C/C++的基本类型,如intdouble等是原子的吗,如ThreadSafe?

它们是否没有数据竞争;也就是说,如果一个线程向这种类型的对象写入数据,而另一个线程从该对象读取数据,那么行为是否定义良好?

如果不是,它依赖于编译器还是其他什么?

推荐答案

不,基本数据类型(例如intdouble)不是原子的,请参见std::atomic.

相反,你可以使用std::atomic<int>std::atomic<double>.

Note: std::atomic是用C++ 11引入的,我的理解是C++之前的C++标准根本就不认识到多线程的存在.


正如@Josh所指出的,std::atomic_flag是原子布尔类型.它是guaranteed to be lock-free个,与std::atomic个专业化认证不同.


引用的文件来自:http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4567.pdf.我很确定这个标准不是免费的,因此这不是最终/官方版本.

1.10多线程执行和数据竞争

  1. 如果其中一个修改内存位置(1.7),另一个读取或修改同一内存位置,则两个表达式求值会发生冲突.
  2. 该库定义了许多原子操作(第29条)和对互斥锁的操作(第30条),这些操作被特别标识为同步操作.这些操作在使一个线程中的赋值对另一个线程可见方面扮演着特殊的角色.在一个或多个存储器位置上的同步操作是消费操作、获取操作、释放操作或获取和释放操作两者.没有相关联的存储器位置的同步操作是围栏,并且可以是获取围栏、释放围栏或获取和释放围栏两者.此外,还有 slack 的原子操作(非同步操作)和原子读-修改-写操作(具有特殊特性).


  1. 如果发生以下情况,两个动作可能同时进行:

29.5原子类型

  1. 对于整型"`char、signed charunsigned charshortunsigned shortintunsigned intlongunsigned longlong longunsigned long longchar16_t、char32_twchar_t,以及标题<cstdint>中TypeDef所需的任何其他类型,原子模板应有明确的专门化.对于每个积分类型,专用化atomic<integral>提供适合于积分类型的附加原子操作.应有一个专门的atomic<bool>,提供29.6.1中规定的一般原子操作..


  1. 应该有原子类模板的指针部分专门化.这些专门化应该具有标准布局、简单的默认构造函数和简单的析构函数.它们都应支持聚合初始化语法.

29.7标志类型和操作

  1. 对类型为ATOM_FLAG的对象的操作应该是无锁的.[注意:因此操作也应该是无地址的.没有其他类型需要无锁操作,因此ATOM_FLAG类型是符合此国际标准所需的最低硬件实现类型.其余类型可以用ATOMICAL_FLAG模拟,尽管其属性不太理想.-尾注]

C++相关问答推荐

设计处理各种数据类型的方法和数据 struct

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

增加getaddrinfo返回的IP地址数量

为什么双重打印与C中的float具有不同的大小时具有相同的值?

Can函数指针指向C++中具有不同参数连续性的函数

1处的解析器错误:yacc语法的语法错误

获取每个循环迭代结束时的当前时间

&;(str[i])和(&;str)[i]有什么区别?

每次除以或乘以整数都会得到0.0000

getline()从c中的外部函数传递指针时输出null

如何在c中使用具有不同变量类型的内存分配?

从BIOS(8086)中读取刻度需要多少?

我可以创建适用于不同endian的 colored颜色 struct 吗?

从整型转换为浮点型可能会改变其值.

try 判断长整数是否为素数

在NASM中链接Linux共享库时出错-';将R_ X86_64_;foo';

如何找出C中分配在堆上的数组的大小?

传递参数:C 和 C++ 中 array 与 *&array 和 &array[0] 的区别

如何修复数组数据与列标题未对齐的问题?

如何转义包含指令中的字符?