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;

}

相关推荐
SunkingYang12 小时前
C++20 vs C++17:新特性对比与用法指南
c++·c++20·特性·版本·新特性·对比·c++17
前进吧-程序员12 小时前
C++20 协程入门实战:从 co_await 到一个 100 行的异步任务调度器
网络·c++·c++20
前进吧-程序员13 小时前
实战:C++20 协程 + io_uring 写一个 400 行的 echo server
网络·c++·c++20
骑着蜗牛撵大象3272 天前
C++20 协程 × 屏障:手写一个 co_await 版 Barrier,让等待不再钉死线程
android·c++20·协程·并发编程·co_await·屏障同步
闻缺陷则喜何志丹3 天前
【c++20】协程与屏障
c++·算法·c++20·携程·屏障
努力努力再努力wz3 天前
【C++高阶系列】C++20 协程底层原理:函数为什么能暂停?从状态机到 Task,彻底串起挂起、恢复与协程调度
开发语言·c++·c++20·1024程序员节
fpcc15 天前
c++20新功能—std::osyncstream
c++·c++20
啦啦啦啦啦zzzz22 天前
一致性哈希
服务器·算法·哈希算法·c++20·分布式存储
keep intensify1 个月前
C++20线程池
c++·算法·c++20
繁华的地方不一定留下你的脚印1 个月前
C++20 concepts:把模板要求写在入口,而不是等一屏报错
c++20