memory_order类型
描述:
该类型是枚举类型,其枚举常量表示内存顺序约束。
为优化程序,编译器和处理器可能会对任何没有依赖关系的语句进行重排;但在多线程中,语句间的依赖关系对编译器和处理器而言通常是不可见的,如果发生重排,可能会引发错误。memory_order指定了在进行原子操作时非原子性的内存访问是如何进行排序的。所有原子操作默认的内存访问顺序是memory_order_seq_cst,但这样可能会损害性能。为优化性能,每个执行原子操作的函数都有一个以_explicit结尾的版本,该版本函数增加了一个memory_order类型参数用以指定内存顺序。
ISO/IEC 9899:2018标准中涉及的表示内存顺序的枚举常量及其含义如下表所示:
枚举常量 | 含义 |
memory_order_relaxed | 该枚举常量表示“松散”内存顺序,可用于任何原子操作函数。这是最弱的内存顺序,对于读操作和写操作没有同步和内存顺序约束,可以不受约束地进行重排;但操作本身的原子性是有保证的。 |
memory_order_consume | 该枚举常量表示“消费”内存顺序,可用于读操作或者读-修改-写操作的原子函数,加载操作(load operation)对受影响的内存位置进行消费操作(consume opertion):当前线程中任何依赖函数返回值的读操作和写操作不会重排到该消费操作之前。其它线程中对相同原子变量的释放操作(release operation)及之前的所有写操作对当前线程该消费操作及以后操作可见。 |
memory_order_acquire | 该枚举常量表示“获取”内存顺序,可用于读操作或者读-修改-写操作的原子函数,加载操作(load operation)对受影响的内存位置进行获取操作(acquire operation):当前线程中所有读操作和写操作不会重排到该获取操作之前。其它线程中对相同原子变量的释放操作(release operation)及之前的所有写操作对当前线程该获取操作及以后操作可见。 |
memory_order_release | 该枚举常量表示“释放”内存顺序,可用于写操作或者读-修改-写操作的原子函数,存储操作(store operation)对受影响的内存位置进行释放操作(release operation):当前线程中的所有读操作和写操作不会重排到该释放操作之后。当前线程截至该释放操作的所有写操作对其它线程中对相同原子变量的获取操作(acquire operation)及以后操作可见;当前线程截至该释放操作的所有写操作对其它线程中对相同原子变量的消费操作(consume operation)及以后操作可见。 |
memory_order_acq_rel | 该枚举常量表示“释放获取”内存顺序,可用于读-修改-写操作的原子函数,加载操作(load operation)对受影响的内存位置进行获取操作(详见memory_order_acquire);存储操作(store operation)对受影响的内存位置进行释放操作(详见memory_order_release)。 |
memory_order_seq_cst | 该枚举常量表示“顺序一致”内存顺序,这是最强的内存顺序,也是默认的内存顺序,可用于任何原子操作函数,加载操作(load operation)对受影响的内存位置进行获取操作(详见memory_order_acquire);存储操作(store operation)对受影响的内存位置进行释放操作(详见memory_order_release)。所有memory_order_seq_cst操作都应存在一个单一全序,该顺序与“happens before”顺序和所有受影响位置的修改顺序一致。不同线程中观察到的内存修改顺序是相同的。 |
在Pelles C编译器<stdatomic.h>头文件中,memory_order类型定义如下:
typedef enum memory_order { memory_order_relaxed = 0, memory_order_consume = 1, memory_order_acquire = 2, memory_order_release = 3, memory_order_acq_rel = 4, memory_order_seq_cst = 5 } memory_order;