@@ -40,11 +40,13 @@ void f() {
40
40
41
41
### 原子类型 ` std::atomic `
42
42
43
- 标准原子类型定义在头文件 [ ` <atomic> ` ] ( https://zh.cppreference.com/w/cpp/header/atomic ) 中。这些类型的操作都是原子的,语言定义中只有这些类型的操作是原子的,虽然也可以用互斥量来模拟原子操作(见上文)。标准的原子的类型实现可能是: * 它们几乎都有一个 ` is_lock_free() ` 成员函数,这个函数可以让用户查询某原子类型的操作是直接用的原子指令(返回 ` true ` ),还是内部用了锁实现(返回 ` false ` )。 *
43
+ 标准原子类型定义在头文件 [ ` <atomic> ` ] ( https://zh.cppreference.com/w/cpp/header/atomic ) 中。这些类型的操作都是原子的,语言定义中只有这些类型的操作是原子的,虽然也可以用互斥量来模拟原子操作(见上文)。
44
44
45
- > 每个 ` std::atomic ` 模板的实例化和全特化均定义一个原子类型。 ** 如果一个线程写入原子对象,同时另一线程从它读取,那么行为有良好定义 ** (数据竞争的细节见 [ 内存模型 ] ( https://zh.cppreference.com/w/cpp/language/memory_model ) )。
45
+ 标准原子类型的实现通常包括一个 ` is_lock_free() ` 成员函数,允许用户查询特定原子类型的操作是否是通过直接的原子指令实现(返回 true),还是通过锁来实现(返回 false )。
46
46
47
- 原子操作可以代替互斥量,来进行同步操作,也能带来更高的性能。但是如果它的内部使用互斥量实现,那么不可能有性能的提升。
47
+ > ** 如果一个线程写入原子对象,同时另一线程从它读取,那么行为有良好定义** (数据竞争的细节见[ 内存模型] ( https://zh.cppreference.com/w/cpp/language/memory_model ) )。
48
+
49
+ 原子操作可以在一些时候代替互斥量,来进行同步操作,也能带来更高的性能。但是如果它的内部使用互斥量实现,那么不可能有性能的提升。
48
50
49
51
在 C++17 中,所有原子类型都有一个 ` static constexpr ` 的数据成员 [ ` is_always_lock_free ` ] ( https://zh.cppreference.com/w/cpp/atomic/atomic/is_always_lock_free ) 。如果当前环境上的原子类型 X 是无锁类型,那么 ` X::is_always_lock_free ` 将返回 ` true ` 。例如:
50
52
@@ -101,7 +103,7 @@ else {
101
103
102
104
因为 `is_always_lock_free` 是编译期常量,所以我们可以使用 C++17 引入的 `constexpr if ` ,它可以在编译阶段进行决策,避免了运行时的判断开销,提高了性能。
103
105
104
- 宏则更是简单了,最基本的预处理器判断,在预处理阶段就选择执行合适的代码 。
106
+ 宏则更是简单了,最基本的预处理器判断,在预处理阶段就选择编译合适的代码 。
105
107
106
108
在实际应用中,如果一个类型的原子操作总是无锁的,我们可以更放心地在性能关键的代码路径中使用它。例如,在高频交易系统、实时系统或者其它需要高并发性能的场景中,无锁的原子操作可以显著减少锁的开销和争用,提高系统的吞吐量和响应时间。
107
109
@@ -111,6 +113,8 @@ else {
111
113
2 . **减少原子操作的频率**:通过批处理等技术,减少对原子操作的调用次数。
112
114
3 . **使用更高效的同步机制**:在一些情况下,其它同步机制(如读写锁)可能比原子操作更高效。
113
115
116
+ 当然,其实很多时候根本没这种性能的担忧,我们很多时候使用原子对象只是为了简单方便,比如 `std::atomic<bool >` 表示状态、`std::atomic<int >` 进行计数等。即使它们是用了锁,那也是封装好了的,起码用着方便,而不需要在代码中引入额外的互斥量来保护,更加简洁。这也是很正常的需求,各位不但要考虑程序的性能,同时也要考虑代码的简洁性、易用性。即使使用原子类型无法带来效率的提升,那也没有负提升。
117
+
114
118
---
115
119
116
120
除了直接使用 `std::atomic` 模板外,也可以使用原子类型的别名。这个数量非常之多,见 [MSVC STL](https:// github.com/microsoft/STL/blob/daeb0a6/stl/inc/atomic#L2745-L2805)。
0 commit comments