Skip to content

Commit 1fc6f7b

Browse files
committed
增加修改源码解析的内容 #12 增加 mermaid 图 #22
1 parent 8714ced commit 1fc6f7b

File tree

1 file changed

+62
-8
lines changed

1 file changed

+62
-8
lines changed

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

+62-8
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
255255

256256
很明显,这是一个函数调用,将我们 `std::async` 的参数全部转发给它,它是重要而直观的。
257257

258-
`_Get_associated_state` 函数根据启动模式(`launch`)来决定创建的异步任务状态对象类型:
258+
[`_Get_associated_state`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L1400-L1410) 函数根据启动模式(`launch`)来决定创建的异步任务状态对象类型:
259259

260260
```cpp
261261
template <class _Ret, class _Fty>
@@ -277,14 +277,14 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
277277
278278
---
279279
280-
**`_Task_async_state` 类型**
280+
**[`_Task_async_state`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L654-L686) 类型**
281281
282282
```cpp
283283
template <class _Rx>
284284
class _Task_async_state : public _Packaged_state<_Rx()>
285285
```
286286

287-
`_Task_async_state` `_Packaged_state` 的派生类,用于异步执行任务。它的构造函数接受一个函数对象,并将其传递给基类 `_Packaged_state` 的构造函数。
287+
`_Task_async_state` 继承自 [`_Packaged_state`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L462-L597),用于异步执行任务。它的构造函数接受一个函数对象,并将其传递给基类 `_Packaged_state` 的构造函数。
288288

289289
`_Packaged_state` 类型只有一个数据成员 `std::function` 类型的对象 `_Fn`,它表示需要执行的异步任务,而它又继承自 _Associated_state。
290290

@@ -294,6 +294,25 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
294294
: public _Associated_state<_Ret>
295295
```
296296
297+
```mermaid
298+
classDiagram
299+
class _Associated_state {
300+
...
301+
}
302+
303+
class _Packaged_state {
304+
-std::function _Fn
305+
}
306+
307+
class _Task_async_state {
308+
-::Concurrency::task<void> _Task
309+
}
310+
311+
_Associated_state <|-- _Packaged_state : 继承
312+
_Packaged_state <|-- _Task_async_state : 继承
313+
314+
```
315+
297316
我们直接看 `_Task_async_state` 类型的构造函数实现即可:
298317

299318
```cpp
@@ -316,18 +335,53 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
316335

317336
这里其实使用到了微软自己实现的 [并行模式库](https://learn.microsoft.com/zh-cn/cpp/parallel/concrt/parallel-patterns-library-ppl?view=msvc-170)(PPL),简而言之 `async` 策略并不是单纯的创建线程让任务执行,而是使用了微软的 `::Concurrency::create_task` ,它从**线程池**中获取线程并执行任务返回包装对象。
318337

319-
`this->_Call_immediate();` 是调用的父类 `_Packaged_state` 的成员函数:
338+
`this->_Call_immediate();` 是调用 `_Task_async_state` 的父类 `_Packaged_state` 的成员函数 `_Call_immediate`
339+
340+
**`_Packaged_state` 有三个偏特化**`_Call_immediate` 自然也拥有三个不同版本,用来应对我们传入的函数对象**返回类型**的三种情况:
341+
342+
- 返回普通类型 [`_Packaged_state<_Ret(_ArgTypes...)>`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L554)
343+
344+
```cpp
345+
void _Call_immediate(_ArgTypes... _Args) {
346+
_TRY_BEGIN
347+
// 调用函数对象并捕获异常 传递返回值
348+
this->_Set_value(_Fn(_STD forward<_ArgTypes>(_Args)...), false);
349+
_CATCH_ALL
350+
// 函数对象抛出异常就记录
351+
this->_Set_exception(_STD current_exception(), false);
352+
_CATCH_END
353+
}
354+
```
355+
356+
- 返回引用类型 [`_Packaged_state<_Ret&(_ArgTypes...)>`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L510)
357+
358+
```cpp
359+
void _Call_immediate(_ArgTypes... _Args) {
360+
_TRY_BEGIN
361+
// 调用函数对象并捕获异常 传递返回值的地址
362+
this->_Set_value(_STD addressof(_Fn(_STD forward<_ArgTypes>(_Args)...)), false);
363+
_CATCH_ALL
364+
// 函数对象抛出异常就记录
365+
this->_Set_exception(_STD current_exception(), false);
366+
_CATCH_END
367+
}
368+
```
369+
370+
- 返回 void 类型 [`_Packaged_state<void(_ArgTypes...)>`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L554)
320371

321372
```cpp
322373
void _Call_immediate(_ArgTypes... _Args) { // call function object
323374
_TRY_BEGIN
324-
// call function object and catch exceptions
325-
this->_Set_value(_Fn(_STD forward<_ArgTypes>(_Args)...), false);
375+
// 调用函数对象并捕获异常 因为返回 void 不获取返回值 而是直接 _Set_value 传递一个 1
376+
_Fn(_STD forward<_ArgTypes>(_Args)...);
377+
this->_Set_value(1, false);
326378
_CATCH_ALL
327-
// function object threw exception; record result
379+
// 函数对象抛出异常就记录
328380
this->_Set_exception(_STD current_exception(), false);
329381
_CATCH_END
330382
}
331383
```
332384
333-
它则调用了 `_Associated_state` 的成员函数(`_Set_value`、`_set_exception`),传递的可调用对象执行结果,以及可能的异常,将结果或异常存储在 `_Associated_state` 中。
385+
说白了,无非是把返回引用类型的可调用对象返回的引用获取地址传递给 `_Set_value`,把返回 void 类型的可调用对象传递一个 1 表示正确执行的状态给 `_Set_value`。
386+
387+
`_Call_immediate` 则又调用了父类 `_Associated_state` 的成员函数(`_Set_value`、`_set_exception`),传递的可调用对象执行结果,以及可能的异常,将结果或异常存储在 `_Associated_state` 中。

0 commit comments

Comments
 (0)