目录
- 1 协程
- 2 实例
- 3 运行
1 协程
协程(Coroutines)是一个可以挂起执行以便稍后恢复的函数。协程是无堆栈的:它们通过返回到调用方来暂停执行,并且恢复执行所需的数据与堆栈分开存储。这允许异步执行的顺序代码(例如,在没有显式回调的情况下处理非阻塞I/O),还支持惰性计算无限序列上的算法和其他用途。
协程类图如下:
2 实例
#include <coroutine> //for std::coroutine_handle std::suspend_never
#include <iostream>
#include <utility>template <class T>
struct task
{struct promise_type{auto get_return_object(){std::cout << "in get_return_object" << std::endl;return task(std::coroutine_handle<promise_type>::from_promise(*this));}std::suspend_always initial_suspend() {std::cout << "in initial_suspend" << std::endl;return {}; }struct final_awaiter{bool await_ready() noexcept{ std::cout << "in final_awaiter.await_ready" << std::endl;return false;}void await_resume() noexcept {std::cout << "in final_awaiter.await_resume" << std::endl;}std::coroutine_handle<>await_suspend(std::coroutine_handle<promise_type> h) noexcept{std::cout << "in final_awaiter.await_suspend" << std::endl;if(auto previous = h.promise().previous; previous){std::cout << "in final_awaiter.await_suspend.previous" << std::endl;return previous;}else{std::cout << "in final_awaiter.await_suspend.noop_coroutine" << std::endl;return std::noop_coroutine();}}};final_awaiter final_suspend() noexcept {std::cout << "in final_suspend" << std::endl;return {}; }void unhandled_exception() {std::cout << "in unhandled_exception" << std::endl;throw; }void return_value(T value) {std::cout << "in return_value" << std::endl;result = std::move(value); }T result;std::coroutine_handle<> previous;};task(std::coroutine_handle<promise_type> h) : coro(h) {}task(task &&) = delete;~task() { coro.destroy(); }struct awaiter{bool await_ready() {std::cout << "in awaiter.await_ready" << std::endl;return false; }T await_resume() {std::cout << "in awaiter.await_resume" << std::endl;return std::move(coro.promise().result);}auto await_suspend(std::coroutine_handle<> h){std::cout << "in awaiter.await_suspend" << std::endl;coro.promise().previous = h;return coro;}std::coroutine_handle<promise_type> coro;};awaiter operator co_await(){ std::cout << "in co_await" << std::endl;return awaiter{coro};}T operator()(){std::cout << "in operator()" << std::endl;coro.resume();return std::move(coro.promise().result);}private:std::coroutine_handle<promise_type> coro;
};task<int> get_random()
{std::cout << "in get_random\n";co_return 4;
}task<int> test()
{task<int> v = get_random();task<int> u = get_random();std::cout << "in test()\n";int x = (co_await v + co_await u);co_return x;
}int main()
{std::cout << "before test\n";task<int> t = test();std::cout << "after test\n";int result = t();std::cout << "after t()\n";std::cout << result << std::endl;return 0;
}
3 运行
before test
in get_return_object 创建协程t
in initial_suspend 挂起t
after test
in operator() 调用t()->{ resume, return result; }
in get_return_object 创建携程v
in initial_suspend 挂起v
in get_return_object 创建携程u
in initial_suspend 挂起u
in test()
in co_await 调用v.co_wait
in co_await 调用u.co_wait
in awaiter.await_ready 调用v.awaiter.await_ready
in awaiter.await_suspend 调用v.awaiter.await_suspend,保存到previous,返回原来的coro
in get_random
in return_value 调用v.promise_type.return_value
in final_suspend 调用v.promise_type.final_suspend,返回final_awaiter
in final_awaiter.await_ready 调用v.final_awaiter.await_ready
in final_awaiter.await_suspend 调用v.final_awaiter.await_suspend
in final_awaiter.await_suspend.previous 返回v之前的previous
in awaiter.await_ready 调用u.awaiter.await_ready
in awaiter.await_suspend 调用u.awaiter.await_suspend,保存到previous,返回原来的coro
in get_random
in return_value 调用u.promise_type.return_value
in final_suspend 调用u.promise_type.final_suspend,返回final_awaiter
in final_awaiter.await_ready 调用u.final_awaiter.await_ready
in final_awaiter.await_suspend 调用u.final_awaiter.await_suspend
in final_awaiter.await_suspend.previous 返回u之前的previous
in awaiter.await_resume 调用v.awaiter.await_resume,返回值
in awaiter.await_resume 调用u.awaiter.await_resume,返回值
in test.x
in return_value 调用t.promise_type.return_value
in final_suspend 调用t.promise_type.final_suspend,返回final_awaiter
in final_awaiter.await_ready 调用t.final_awaiter.await_ready
in final_awaiter.await_suspend 调用t.final_awaiter.await_suspend
in final_awaiter.await_suspend.noop_coroutine 返回noop_coroutine,不做后续操作
after t()
8
说明:
- 由于t挂起后立即调用resume,所以t的awaiter没有被调用,所以t.final_awaiter.await_suspend返回的是noop_coroutine