C/C++的基本类型,如int
、double
等是原子的吗,如ThreadSafe?
它们是否没有数据竞争;也就是说,如果一个线程向这种类型的对象写入数据,而另一个线程从该对象读取数据,那么行为是否定义良好?
如果不是,它依赖于编译器还是其他什么?
C/C++的基本类型,如int
、double
等是原子的吗,如ThreadSafe?
它们是否没有数据竞争;也就是说,如果一个线程向这种类型的对象写入数据,而另一个线程从该对象读取数据,那么行为是否定义良好?
如果不是,它依赖于编译器还是其他什么?
不,基本数据类型(例如int
、double
)不是原子的,请参见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.7),另一个读取或修改同一内存位置,则两个表达式求值会发生冲突.
- 该库定义了许多原子操作(第29条)和对互斥锁的操作(第30条),这些操作被特别标识为同步操作.这些操作在使一个线程中的赋值对另一个线程可见方面扮演着特殊的角色.在一个或多个存储器位置上的同步操作是消费操作、获取操作、释放操作或获取和释放操作两者.没有相关联的存储器位置的同步操作是围栏,并且可以是获取围栏、释放围栏或获取和释放围栏两者.此外,还有 slack 的原子操作(非同步操作)和原子读-修改-写操作(具有特殊特性).
- 如果发生以下情况,两个动作可能同时进行:
- 对于整型"`char、
signed char
、unsigned char
、short
、unsigned short
、int
、unsigned int
、long
、unsigned long
、long long
、unsigned long long
、char16_
t、char32_t
、wchar_t
,以及标题<cstdint>
中TypeDef所需的任何其他类型,原子模板应有明确的专门化.对于每个积分类型,专用化atomic<integral>
提供适合于积分类型的附加原子操作.应有一个专门的atomic<bool>
,提供29.6.1中规定的一般原子操作..
- 应该有原子类模板的指针部分专门化.这些专门化应该具有标准布局、简单的默认构造函数和简单的析构函数.它们都应支持聚合初始化语法.
- 对类型为ATOM_FLAG的对象的操作应该是无锁的.[注意:因此操作也应该是无地址的.没有其他类型需要无锁操作,因此ATOM_FLAG类型是符合此国际标准所需的最低硬件实现类型.其余类型可以用ATOMICAL_FLAG模拟,尽管其属性不太理想.-尾注]