@@ -253,7 +253,9 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
253
253
254
254
` _Get_associated_state<_Ret>(_Policy, _Fake_no_copy_callable_adapter<_Fty, _ArgTypes...>(_STD forward<_Fty>(_Fnarg), _STD forward<_ArgTypes>(_Args)...)) `
255
255
256
- 很明显,这是一个函数调用,将我们 ` std::async ` 的参数全部转发给它,它是重要而直观的,代码如下:
256
+ 很明显,这是一个函数调用,将我们 ` std::async ` 的参数全部转发给它,它是重要而直观的。
257
+
258
+ ` _Get_associated_state ` 函数根据启动模式(` launch ` )来决定创建的异步任务状态对象类型:
257
259
258
260
``` cpp
259
261
template <class _Ret , class _ Fty>
@@ -271,4 +273,61 @@ _NODISCARD_ASYNC future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>>
271
273
272
274
`_Get_associated_state` 函数返回一个 `_Associated_state` 指针,该指针指向一个新的 `_Deferred_async_state` 或 `_Task_async_state` 对象。这两个类分别对应于异步任务的两种不同执行策略:**延迟执行**和**异步执行**。
273
275
274
- > 这也就是证明了在 MSVC STL 的实现中,`launch::async | launch::deferred` 与 `launch::async` 执行策略**毫无区别**。这段代码的 `switch` 语句有两个 `case` 和一个 `default`,如你所见,`case launch::async` 是为空的,除了 `launch::deferred` 最终都会进入 `default`,即都执行 `launch::async` 策略。
276
+ > 这段代码也很好的说明在 MSVC STL 中,`launch::async | launch::deferred` 和 `launch::async` 的行为是相同的,即都是异步执行。
277
+
278
+ ---
279
+
280
+ **`_Task_async_state` 类型**
281
+
282
+ ```cpp
283
+ template <class _Rx>
284
+ class _Task_async_state : public _Packaged_state<_Rx()>
285
+ ```
286
+
287
+ ` _Task_async_state ` 是 ` _Packaged_state ` 的派生类,用于异步执行任务。它的构造函数接受一个函数对象,并将其传递给基类 ` _Packaged_state ` 的构造函数。
288
+
289
+ ` _Packaged_state ` 类型只有一个数据成员 ` std::function ` 类型的对象 ` _Fn ` ,它表示需要执行的异步任务,而它又继承自 _ Associated_state。
290
+
291
+ ``` cpp
292
+ template <class _Ret , class... _ ArgTypes>
293
+ class _ Packaged_state<_ Ret(_ ArgTypes...)>
294
+ : public _ Associated_state<_ Ret>
295
+ ```
296
+
297
+ 我们直接看 `_Task_async_state` 类型的构造函数实现即可:
298
+
299
+ ```cpp
300
+ template <class _Fty2>
301
+ _Task_async_state(_Fty2&& _Fnarg) : _Mybase(_STD forward<_Fty2>(_Fnarg)) {
302
+ _Task = ::Concurrency::create_task([this]() { // do it now
303
+ this->_Call_immediate();
304
+ });
305
+
306
+ this->_Running = true;
307
+ }
308
+ ```
309
+
310
+ 它的数据成员:
311
+
312
+ ``` cpp
313
+ private:
314
+ ::Concurrency::task<void > _Task;
315
+ ```
316
+
317
+ 这里其实使用到了微软自己实现的 [ 并行模式库] ( https://learn.microsoft.com/zh-cn/cpp/parallel/concrt/parallel-patterns-library-ppl?view=msvc-170 ) (PPL),简而言之 ` async ` 策略并不是单纯的创建线程让任务执行,而是使用了微软的 ` ::Concurrency::create_task ` ,它从** 线程池** 中获取线程并执行任务返回包装对象。
318
+
319
+ ` this->_Call_immediate(); ` 是调用的父类 ` _Packaged_state ` 的成员函数:
320
+
321
+ ``` cpp
322
+ void _Call_immediate (_ ArgTypes... _ Args) { // call function object
323
+ _ TRY_BEGIN
324
+ // call function object and catch exceptions
325
+ this->_ Set_value(_ Fn(_ STD forward<_ ArgTypes>(_ Args)...), false);
326
+ _ CATCH_ALL
327
+ // function object threw exception; record result
328
+ this->_ Set_exception(_ STD current_exception(), false);
329
+ _ CATCH_END
330
+ }
331
+ ```
332
+
333
+ 它则调用了 `_Associated_state` 的成员函数(`_Set_value`、`_set_exception`),传递的可调用对象执行结果,以及可能的异常,将结果或异常存储在 `_Associated_state` 中。
0 commit comments