Skip to content

Commit 25043eb

Browse files
committed
修改 async 源码解析内容,将 _Task_async_state 与 _Deferred_async_state 一起描述,进行补充。
修改 mermaid 继承图,加入 _Deferred_async_state
1 parent f97b023 commit 25043eb

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

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

+30-6
Original file line numberDiff line numberDiff line change
@@ -277,16 +277,18 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
277277
278278
---
279279
280-
**[`_Task_async_state`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L654-L686) 类型**
280+
**[`_Task_async_state`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L654-L686) 与 `_Deferred_async_state` 类型**
281281
282282
```cpp
283283
template <class _Rx>
284284
class _Task_async_state : public _Packaged_state<_Rx()>
285+
template <class _Rx>
286+
class _Deferred_async_state : public _Packaged_state<_Rx()>
285287
```
286288

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

289-
`_Packaged_state` 类型只有一个数据成员 `std::function` 类型的对象 `_Fn`它表示需要执行的异步任务,而它又继承自 _Associated_state。
291+
**`_Packaged_state` 类型只有一个数据成员 `std::function` 类型的对象 `_Fn`它用来存储需要执行的异步任务**,而它又继承自 `_Associated_state`
290292

291293
```cpp
292294
template <class _Ret, class... _ArgTypes>
@@ -308,12 +310,17 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
308310
-::Concurrency::task<void> _Task
309311
}
310312
313+
class _Deferred_async_state {
314+
...
315+
}
316+
311317
_Associated_state <|-- _Packaged_state : 继承
312318
_Packaged_state <|-- _Task_async_state : 继承
319+
_Packaged_state <|-- _Deferred_async_state : 继承
313320
314321
```
315322

316-
我们直接看 `_Task_async_state` 类型的构造函数实现即可:
323+
我们直接先看 `_Task_async_state``_Deferred_async_state` 类型的构造函数实现即可:
317324

318325
```cpp
319326
template <class _Fty2>
@@ -324,16 +331,21 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
324331

325332
this->_Running = true;
326333
}
334+
template <class _Fty2>
335+
_Deferred_async_state(const _Fty2& _Fnarg) : _Packaged_state<_Rx()>(_Fnarg) {}
336+
337+
template <class _Fty2>
338+
_Deferred_async_state(_Fty2&& _Fnarg) : _Packaged_state<_Rx()>(_STD forward<_Fty2>(_Fnarg)) {}
327339
```
328340
329-
它的数据成员:
341+
`_Task_async_state` 它的数据成员:
330342
331343
```cpp
332344
private:
333345
::Concurrency::task<void> _Task;
334346
```
335347

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

338350
`this->_Call_immediate();` 是调用 `_Task_async_state` 的父类 `_Packaged_state` 的成员函数 `_Call_immediate`
339351

@@ -385,3 +397,15 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
385397
说白了,无非是把返回引用类型的可调用对象返回的引用获取地址传递给 `_Set_value`,把返回 void 类型的可调用对象传递一个 1 表示正确执行的状态给 `_Set_value`。
386398
387399
`_Call_immediate` 则又调用了父类 `_Associated_state` 的成员函数(`_Set_value`、`_set_exception`),传递的可调用对象执行结果,以及可能的异常,将结果或异常存储在 `_Associated_state` 中。
400+
401+
`_Deferred_async_state` 并不会在线程中执行任务,但它同样调用 `_Call_immediate` 函数执行保有的函数对象,它有一个 `_Run_deferred_function` 函数:
402+
403+
```cpp
404+
void _Run_deferred_function(unique_lock<mutex>& _Lock) override { // run the deferred function
405+
_Lock.unlock();
406+
_Packaged_state<_Rx()>::_Call_immediate();
407+
_Lock.lock();
408+
}
409+
```
410+
411+
然后也就和上面说的没什么区别了 。

0 commit comments

Comments
 (0)