Skip to content

Commit 566e3b2

Browse files
committed
更新 async 源码解析部分内容
1 parent 2fae072 commit 566e3b2

File tree

1 file changed

+75
-3
lines changed

1 file changed

+75
-3
lines changed

Diff for: md/详细分析/03async与future源码解析.md

+75-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
3838
3939
1. **模板参数和函数体外部信息**:
4040
41+
- `_EXPOPT_STD` 是一个宏,当 `_BUILD_STD_MODULE` 宏定义且启用了 C++20 时,会被定义为 `export`,以便导出模块;否则它为空。
42+
4143
- `_Fty` 表示可调用对象的类型。
4244
- `_ArgTypes` 是一个类型形参包,表示调用该可调用对象所需的参数类型。
4345
- `_NODISCARD_ASYNC` 是一个宏,表示属性 `[[nodiscard]]`,用于标记此函数的返回值不应被忽略。
@@ -80,7 +82,7 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
8082

8183
`using _Ptype = typename _P_arg_type<_Ret>::type;`
8284

83-
- 定义 `_Ret` 类型别名,它是使用 `_ArgTypes` 类型参数调用 `_Fty` 类型的可调用对象后得到的结果类型。也就是我们传入的可调用对象的返回类型;同样使用了 `_Invoke_result_t``decay_t`
85+
- 定义 `_Ret` 类型别名,它是使用 `_ArgTypes` 类型参数调用 `_Fty` 类型的可调用对象后得到的结果类型。也就是我们传入的可调用对象的返回类型;同样使用了 `_Invoke_result_t`(等价于 [`std::invoke_result_t`](https://zh.cppreference.com/w/cpp/types/result_of)`decay_t`
8486

8587
- 其实 `_Ptype` 的定义确实在大多数情况下和 `_Ret` 是相同的,类模板 _P_arg_type 只是为了处理引用类型以及 void 的情况,参见 `_P_arg_type` 的实现:
8688

@@ -101,6 +103,76 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
101103
};
102104
```
103105

104-
`_Ptype`:处理异步任务返回值的方式类型,它在语义上强调了异步任务返回值的处理方式,具有不同的实现逻辑和使用场景。在当前我们难以直接展示它的作用,将在后文详细探讨 `_Promise` 类型的内部实现,展示此别名的意义。
106+
`_Ptype`:处理异步任务返回值的方式类型,它在语义上强调了异步任务返回值的处理方式,具有不同的实现逻辑和使用场景。在当前我们难以直接展示它的作用,不过可以推测,这个“`P`” 表示的是后文将使用的 `_Promise` 类模板。也就是说,定义 `_Ptype` 是为了配合 `_Promise` 的使用。我们将会在后文详细探讨 `_Promise` 类型的内部实现,并进一步解释 `_Ptype` 的具体作用。
107+
108+
5. `_Promise<_Ptype> _Pr`
109+
110+
`_Promise` 类型本身不重要,很简单,关键还在于其存储的数据成员。
111+
112+
```cpp
113+
template <class _Ty>
114+
class _Promise {
115+
public:
116+
_Promise(_Associated_state<_Ty>* _State_ptr) noexcept : _State(_State_ptr, false), _Future_retrieved(false) {}
117+
118+
_Promise(_Promise&&) = default;
119+
120+
_Promise& operator=(_Promise&&) = default;
121+
122+
void _Swap(_Promise& _Other) noexcept {
123+
_State._Swap(_Other._State);
124+
_STD swap(_Future_retrieved, _Other._Future_retrieved);
125+
}
126+
127+
const _State_manager<_Ty>& _Get_state() const noexcept {
128+
return _State;
129+
}
130+
_State_manager<_Ty>& _Get_state() noexcept {
131+
return _State;
132+
}
133+
134+
_State_manager<_Ty>& _Get_state_for_set() {
135+
if (!_State.valid()) {
136+
_Throw_future_error2(future_errc::no_state);
137+
}
138+
139+
return _State;
140+
}
141+
142+
_State_manager<_Ty>& _Get_state_for_future() {
143+
if (!_State.valid()) {
144+
_Throw_future_error2(future_errc::no_state);
145+
}
146+
147+
if (_Future_retrieved) {
148+
_Throw_future_error2(future_errc::future_already_retrieved);
149+
}
150+
151+
_Future_retrieved = true;
152+
return _State;
153+
}
154+
155+
bool _Is_valid() const noexcept {
156+
return _State.valid();
157+
}
158+
159+
bool _Is_ready() const noexcept {
160+
return _State._Is_ready();
161+
}
162+
163+
_Promise(const _Promise&) = delete;
164+
_Promise& operator=(const _Promise&) = delete;
165+
166+
private:
167+
_State_manager<_Ty> _State;
168+
bool _Future_retrieved;
169+
};
170+
```
171+
172+
`_Promise` 类是对 `_State_manager` 类型的**包装**,并增加了一个表示状态的成员 `_Future_retrieved`。
105173
106-
5.
174+
状态成员用于跟踪 `_Promise` 是否已经调用过 `_Get_state_for_future()` 成员函数;它默认为 `false`,在**第一次**调用 `_Get_state_for_future()` 成员函数时被置为 `true`,如果二次调用,就会抛出 [`future_errc::future_already_retrieved`](https://zh.cppreference.com/w/cpp/thread/future_errc) 异常。
175+
176+
> 这类似于 `std::promise` 调用 [`get_future()`](https://zh.cppreference.com/w/cpp/thread/promise/get_future) 成员函数。[测试](https://godbolt.org/z/8anc9b3PT)。
177+
178+
`_Promise` 的构造函数

0 commit comments

Comments
 (0)