c++ 20 协程例子

#include <chrono>

#include <coroutine>

#include <functional>

#include <iostream>

#include <queue>

#include <string>

#include <thread>

using task = std::function<void(const std::string&)>;

class executor {

private:

std::thread work_thread_;

std::queue<task> tasks_;

public:

void add_task(task t) { tasks_.emplace(std::move(t)); }

void run() {

work_thread_ = std::thread(this() {

uint64_t times = 1;

std::cout << "executor thread: " << std::this_thread::get_id() << "\n";

while (true) {

auto& task = tasks_.front();

task(std::to_string(times));

times++;

tasks_.pop();

using namespace std::chrono_literals;

std::this_thread::sleep_for(1000ms);

}

});

if (work_thread_.joinable()) {

work_thread_.join();

}

}

};

class coroutine_task {

public:

struct promise_type {

std::suspend_never initial_suspend() noexcept { return {}; }

std::suspend_always final_suspend() noexcept { return {}; }

void unhandled_exception() noexcept {}

coroutine_task get_return_object() noexcept {

auto tk = coroutine_task{

std::coroutine_handle<promise_type>::from_promise(*this) };

return tk;

}

/*void return_value(int v) noexcept {}*/

void return_void() noexcept {}

std::suspend_always yield_value(std::string&& from) noexcept {

value_ = std::move(from);

return {};

}

std::string value_;

};

private:

std::coroutine_handle<promise_type> coro_;

public:

coroutine_task(std::coroutine_handle<promise_type> h) : coro_(h) {}

~coroutine_task() {

if (coro_) {

coro_.destroy();

}

}

std::string value() { return coro_.promise().value_; }

};

template <typename R, typename Executor = executor>

struct awaitable {

private:

R buf_;

Executor& e_;

std::coroutine_handle<> coro_handle_;

public:

awaitable(Executor& e) : e_(e) {}

bool await_ready() noexcept { return false; }

R await_resume() noexcept { return buf_; }

void await_suspend(std::coroutine_handle<> p) noexcept {

coro_handle_ = p;

}

void async_start() {

e_.add_task(this(const R& times) {

std::cout << "async resume thread: " << std::this_thread::get_id() << "\n";

buf_ = times;

coro_handle_.resume();

});

}

};

auto async_read(executor& e) {

awaitable<std::string> aw{ e };

aw.async_start();

return aw;

}

coroutine_task coro_read1(executor& e) {

std::cout << "coro_read1 begin thread: " << std::this_thread::get_id() << "\n";

for (;;) {

auto value = co_await async_read(e);

std::cout << "1、coro_read1: " << value << " thread: " << std::this_thread::get_id() << "\n";

value = co_await async_read(e);

std::cout << "2、coro_read1: " << value << " thread: " << std::this_thread::get_id() << "\n";

}

}

coroutine_task coro_read2(executor& e) {

std::cout << "coro_read2 begin thread: " << std::this_thread::get_id() << "\n";

for (;;) {

auto value = co_await async_read(e);

std::cout << "coro_read2: " << value << " thread: " << std::this_thread::get_id() << "\n";

}

}

int main() {

executor e;

auto cr1 = coro_read1(e);

auto cr2 = coro_read2(e);

e.run();

return 0;

}

相关推荐
A_cainiao_A3 天前
C++20:std::stop_source让线程说停就听
开发语言·c++20
小小龙学IT7 天前
C++20 Ranges 库实现原理深度解析:从视图适配器到管道运算符
c++20
Billy1213811 天前
C++20 Concepts:约束与概念的现代范式
c++20·c++进阶学习
可爱系程序猿11 天前
mfc90.dll 缺失如何处理?VC++ 2008 运行库与并行程序集排查记录
程序人生·电脑·c++20
code_pgf12 天前
C++11 / C++14 / C++17 / C++20 新特性总结
c++·c++20
C语言Plus13 天前
C++ SqlBuilder一个简单、灵活且类型安全的 C++ SQL 构建器库
数据库·sql·安全·c++20
CHANG_THE_WORLD23 天前
C++20 协程从零入门:用 ASCII 图彻底理解 `co_await`、协程帧与异步执行
c++20
无限的鲜花1 个月前
协程本质是函数加状态机——零基础深入浅出 C++20 协程
c++·算法·c++20
十五年专注C++开发2 个月前
全面深入了解C++20 范围库(std::ranges)
c++20·管道·哨兵·视图·ranges
小小龙学IT2 个月前
C++20 协程深度解析:从原理到高性能异步框架实战
junit·c++20