C语言多线程与预处理指令全解析
1. 原子操作与内存顺序
在函数参数声明中,占位符A代表任何原子类型,参数obj是指向任意给定原子对象的指针。在优化程序代码时,编译器和处理器可以自由重排不相互依赖的指令顺序。例如, a = 0; b = 1;
这两条赋值语句的执行顺序可以任意。但在多线程环境中,这种优化可能导致错误,因为不同线程中内存操作之间的依赖关系通常对编译器或处理器不可见。
原子对象默认可以防止这种重排,但防止优化可能意味着牺牲速度。有经验的程序员可以通过显式使用内存顺序要求较低的原子操作来提高性能。对于每个执行原子操作的函数,如 atomic_store()
,都有一个接受 memory_order
类型额外参数的版本,这些函数的名称以 _explicit
结尾,如 atomic_store_explicit()
。
memory_order
类型是一个枚举,定义了以下常量来指定给定的内存顺序要求:
| 常量 | 说明 |
| ---- | ---- |
| memory_order_relaxed
| 调用者指定没有内存顺序要求,编译器可以自由更改操作顺序 |
| memory_order_release
| 对原子对象A的写访问执行释放操作,该操作的效果是,给定线程中所有先前的内存访问操作对在A上执行获取操作的另一个线程可见 |
| memory_order_acqui