c++20协程实现await及suspend效果
例子是掌握c++20协程的的起点,网上很多的协程资料说的很复杂,但是例子举得都太差劲了,我这里写了一个可以await与suspend的列子。
1. 协程的基本框架
// suspend.cpp
#include <chrono>
#include <coroutine>
#include <functional>
#include <iostream>
#include <memory>
#include <thread>
struct suspend {
struct promise_type {
promise_type() {}
suspend get_return_object() {
return {std::coroutine_handle<suspend::promise_type>::from_promise(*this)};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
typedef std::coroutine_handle<suspend::promise_type> suspendHandler;
suspendHandler handle_; // 这个变量名可以随便起
};
typedef std::function<void(suspend::suspendHandler, int *)> AwaiterFunction;
template <typename T>
struct await {
AwaiterFunction fun;
std::shared_ptr<T> ptr = std::make_shared<T>();
await(AwaiterFunction fun) : fun(fun){};
bool await_ready() { return false; }
void await_suspend(suspend::suspendHandler handle) {
T *p = ptr.get();
fun(handle, p);
}
std::shared_ptr<int> await_resume() { return ptr; }
};
2. 测试方法
// suspend.cpp
await<int> invokeService() {
auto wait = await<int>([](suspend::suspendHandler handle, int *p) {
// *p = 2025;
// handle.resume();
int *ptr = p;
std::thread([handle, ptr]() mutable {
*ptr = 2023;
std::cout << "sleep 2 seconds \n";
std::this_thread::sleep_for(std::chrono::seconds(2));
handle.resume(); // 可以简写为 handle();
}).detach();
});
return wait;
}
suspend test() {
auto rc = co_await invokeService();
std::cout << "rc = " << rc << std::endl;
std::cout << "3 thread id=" << std::this_thread::get_id() << "\n";
}
3. main函数测试
// suspend.cpp
int main() {
std::cout << "1 thread id=" << std::this_thread::get_id() << "\n";
test();
std::cout << "2 thread id=" << std::this_thread::get_id() << "\n";
std::this_thread::sleep_for(std::chrono::seconds(4));
return 0;
}
4. makefile
app : suspend.cpp
rm -rf ./app
g++ -o $@ $^ -std=c++2a
5. 执行结果
# ./app
1 thread id=140041734599616
2 thread id=140041734599616
sleep 2 seconds
rc = 0x560c1bdde350
3 thread id=140041734583872
作者 :秋时
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。