Rei*_*izo 8 c++ coroutine async-await c++-coroutine
在 C++ 协程中,等待者类型(即/的参数类型co_await和返回类型)需要、和三个方法。我知道在协程挂起/恢复的情况下调用1 的顺序。initial_suspendfinal_suspendawait_ready()await_suspend(std::coroutine_handle<...>)await_resume()
但我不清楚要求采用独特await_ready方法的理由是什么。当返回时true, 的调用await_suspend被阻止(并随之完全暂停)。然而,只需true从 中返回即可实现相同的效果await_suspend。
在这篇博客文章中,作者 David Mazi\xc3\xa8res 说
\n\n\n\n
await_ready是一种优化。如果返回true,则co_await不会暂停该函数。当然,您可以await_suspend通过恢复(或不挂起)当前协程来实现相同的效果,但在调用之前await_suspend,编译器必须将所有状态捆绑到协程句柄引用的堆对象中,这可能会很昂贵。
然而,对我来说,这似乎不是一个有效的论点:(可能是堆)分配的协程状态需要在promise_type::get_return_object()调用之前创建,并且总是被调用,因为promies_type-instance 是协程状态的一部分。因此,无论我们是否调用,句柄引用的协程状态都会被创建await_suspend。
回到将我的想法转化为代码的问题:我看不出在哪种情况下重写
\nstruct awaiter\n{\n bool await_ready() { /* <arbitrary-await-ready-body> */ }\n void /*| bool*/ await_suspend(std::coroutine_handle<...>) { /* <arbitrary-await-suspend-body> */ }\n\n <any> await_resume() { ... }\n};\nRun Code Online (Sandbox Code Playgroud)\n到
\nstruct awaiter\n{\n bool await_ready() { return false; } // always false\n bool await_suspend(std::coroutine_handle<...>)\n {\n if (await_ready_result()) // effectively moved await_ready into await_suspend\n return false;\n /* <arbitrary-await-suspend-body> */\n return true;\n }\n\n <any> await_resume() { ... }\nprivate:\n bool await_ready_result() { /* <arbitrary-await-ready-body> */ }; // could just be "in-lined" into await_suspend\n};\nRun Code Online (Sandbox Code Playgroud)\n将不适用。在后一种情况下,awaiter_ready它已过时,但不会失去任何灵活性2。那么,distinct 有什么用呢awaiter_ready?
我想到的一件事是,当\ 的实现任意复杂时,await_ready可以保留它,这可能允许进行一些优化,但这似乎过于具体,无法成为实际的基本原理。noexceptawait_suspend
1:参见文章https://www.modernnescpp.com/index.php/a-generic-data-stream-with-coroutines-in-c-20的等待工作流程部分中的伪代码块
\n2await_suspend :我忽略了返回 some 的情况std::coroutine_handle,主要是因为我也没有看到它的特殊用途。毕竟,您可以简单地调用some_handle.resume()最后一个语句,而不是返回它,而是返回void/ true。请随意向我介绍一下这一点。
| 归档时间: |
|
| 查看次数: |
1428 次 |
| 最近记录: |