目录
- 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