C/C ++基本类型是原子类型吗? [英] Are C/C++ fundamental types atomic?

查看:412
本文介绍了C/C ++基本类型是原子类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是原子类型的C/C ++基本类型,例如intdouble等.线程安全的?

他们是否摆脱了数据竞争;也就是说,如果一个线程向这种类型的对象写入而另一线程从该对象读取,则行为是否定义明确?

如果不是,这取决于编译器还是其他工具?

解决方案

否,基本数据类型(例如intdouble)不是原子的,请参见 std::atomic_flag 是原子布尔类型.与std::atomic专门技术不同,它保证无锁.


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

1.10多线程执行和数据争用

  1. 如果两个表达式求值中的一个修改了内存位置(1.7),而另一个表达式读取或修改了相同的内存位置,则冲突.
  2. 该库定义了许多原子操作(第29章)和互斥锁上的操作(第30章),这些操作被专门标识为同步操作.这些操作在使一个线程中的分配对另一线程可见时起着特殊的作用.在一个或多个存储器位置上的同步操作是消耗操作,获取操作,释放操作,或者是获取和释放操作两者.没有关联的内存位置的同步操作是隔离区,可以是获取隔离区,释放隔离区,也可以是获取隔离区和释放隔离区.此外,还有宽松的原子操作(不是同步操作)和原子读-修改-写操作(具有特殊特征).


  1. 如果
    (23.1)—它们是由不同的线程执行的,或者
    (23.2)—它们是无序列的,并且至少有一个由信号处理程序执行.
    如果一个程序的执行包含两个潜在的并发冲突操作,其中至少一个不是原子操作,并且没有一个先于另一个发生,则执行该程序将导致数据争用,除了以下所述的信号处理程序的特殊情况.任何此类数据争用都会导致未定义的行为.

29.5原子类型

  1. 对于整数类型``char,signed charunsigned charshortunsigned shortintunsigned intlonglong longunsigned long longchar16_ t,char32_twchar_t,以及标头<cstdint>中typedef所需的任何其他类型.对于每个整数类型积分,专业化atomic<integral>提供适合于整数类型的其他原子操作.应该有一个专门化的atomic<bool>,它提供了29.6.1 ..
  2. 中指定的常规原子操作.


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

29.7标志类型和操作

  1. 对atomic_flag类型的对象的操作应是无锁的. [注意:因此,操作也应该是无地址的.没有其他类型需要无锁操作,因此atomic_flag类型是符合此国际标准所需的最小硬件实现类型.其余类型可以使用atomic_flag进行仿真,尽管其属性不理想. —尾注]

Are C/C++ fundamental types, like int, double, etc., atomic, e.g. threadsafe?

Are they free from data races; that is, if one thread writes to an object of such a type while another thread reads from it, is the behavior well-defined?

If not, does it depend on the compiler or something else?

解决方案

No, fundamental data types (e.g., int, double) are not atomic, see std::atomic.

Instead you can use std::atomic<int> or std::atomic<double>.

Note: std::atomic was introduced with C++11 and my understanding is that prior to C++11, the C++ standard didn't recognize the existence of multithreading at all.


As pointed out by @Josh, std::atomic_flag is an atomic boolean type. It is guaranteed to be lock-free, unlike the std::atomic specializations.


The quoted documentation is from: http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4567.pdf. I'm pretty sure the standard is not free and therefore this isn't the final/official version.

1.10 Multi-threaded executions and data races

  1. Two expression evaluations conflict if one of them modifies a memory location (1.7) and the other one reads or modifies the same memory location.
  2. The library defines a number of atomic operations (Clause 29) and operations on mutexes (Clause 30) that are specially identified as synchronization operations. These operations play a special role in making assignments in one thread visible to another. A synchronization operation on one or more memory locations is either a consume operation, an acquire operation, a release operation, or both an acquire and release operation. A synchronization operation without an associated memory location is a fence and can be either an acquire fence, a release fence, or both an acquire and release fence. In addition, there are relaxed atomic operations, which are not synchronization operations, and atomic read-modify-write operations, which have special characteristics.


  1. Two actions are potentially concurrent if
    (23.1) — they are performed by different threads, or
    (23.2) — they are unsequenced, and at least one is performed by a signal handler.
    The execution of a program contains a data race if it contains two potentially concurrent conflicting actions, at least one of which is not atomic, and neither happens before the other, except for the special case for signal handlers described below. Any such data race results in undefined behavior.

29.5 Atomic types

  1. There shall be explicit specializations of the atomic template for the integral types ``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, and any other types needed by the typedefs in the header <cstdint>. For each integral type integral, the specialization atomic<integral> provides additional atomic operations appropriate to integral types. There shall be a specialization atomic<bool> which provides the general atomic operations as specified in 29.6.1..


  1. There shall be pointer partial specializations of the atomic class template. These specializations shall have standard layout, trivial default constructors, and trivial destructors. They shall each support aggregate initialization syntax.

29.7 Flag type and operations

  1. Operations on an object of type atomic_flag shall be lock-free. [ Note: Hence the operations should also be address-free. No other type requires lock-free operations, so the atomic_flag type is the minimum hardware-implemented type needed to conform to this International standard. The remaining types can be emulated with atomic_flag, though with less than ideal properties. — end note ]

这篇关于C/C ++基本类型是原子类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆