协程笔记
协程的目的是为了描述异步逻辑。
对于多线程来说线程数一多,简单来说就是慢,而协程是一种轻量级异步。
协程的好处
1. 性能
具体细节表示看不懂,只知道性能更高就行了。
2. 语法
别人都说语法简单,初学的我表示这是什么?看不懂啊!!!
2.1 std::coroutine_handle<promise_type>
std::coroutine_handle
是c++20中的一个新类型,用于管理协程的状态和控制协程的进行。简单来说就是指代协程。在协程中,每个协程都有一个与之相关联的 promise_type 类型的对象,它负责协程的管理和控制。
std::coroutine_handle
提供了resume()、destory()、done()
控制协程状态的恢复、销毁、查询。
2.2 promise_type
promise_type
是协程中最重要的部分。在定义一个协程时,需要定义一个promise_type类型,其中包括get_retrurn_object()、initial_suspend()、final_suspend()、yield_value()、return_void()、unhandled_exception()
等函数。
2.3 交互方式
通过co_yield、co_await、co_return
等关键字与协程进行交互。
2.3.1 co_await
std::suspend_never initial_suspend() noexcept { return {};}
决定启动一个协程的时候一开始是否暂停。
struct suspend_never
{
constexpr bool await_ready() const noexcept { return true; } //true不暂停 false暂停
...
};
co_await是一个运算符可以被重载。
template<typename T>
inline auto operator co_await(const (类型名)<T>& x) {
std::cout<<"operator co_await 被调用";
return x;
}
协程开始的时候会调用promise.initial_suspend()并co_await它的结果
#include <iostream>
#include <coroutine>
struct promise {
struct promise_type {
promise get_return_object() {
return { std::coroutine_handle<promise_type>::from_promise(*this) };
}
std::suspend_never initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
std::coroutine_handle<promise_type>_h;
};
struct Input {
bool await_ready() {
return false;
}
void await_suspend(std::coroutine_handle<>h) {}
void await_resume() {}
};
promise func() {
Input t;
std::cout<<"协程开始\n";
co_await t;
std::cout<<"协程结束\n";
}
int main() {
promise result = func();
std::cout<<"main\n";
result._h.resume();
}
以上实现了一个暂停的demo,如果没有暂停实际输出结果应为协程开始、协程结束、main,而实际结果是协程开始、main、协程结束。
对于Input内部还有await_suspend()、await_resume()两个成员函数,这是co_await要求的。
2.3.2 co_yield 用于生成值
co_yield 和 co_await类似,只是能够调用yield_value()。