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;

}

相关推荐
_不会dp不改名_17 天前
C++ 20: Concepts 与Requires
开发语言·c++20
arbboter22 天前
【C++20】新特性探秘:提升现代C++开发效率的利器
c++·c++20·新特性·span·结构化绑定·初始化变量·模板参数推导
猿饵块1 个月前
c++20--std::format
c++20
mrbone111 个月前
C++-关于协程的一些思考
开发语言·数据库·c++·c++20·协程·异步·coroutines
xiaolang_8616_wjl2 个月前
c++文字游戏_闯关打怪
开发语言·数据结构·c++·算法·c++20
十年编程老舅2 个月前
跨越十年的C++演进:C++20新特性全解析
c++·c++11·c++20·c++14·c++23·c++17·c++新特性
xiaolang_8616_wjl2 个月前
c++游戏_小恐龙(开源)
开发语言·数据结构·c++·算法·游戏·开源·c++20
a东方青3 个月前
[蓝桥杯C++ 2024 国 B ] 立定跳远(二分)
c++·算法·蓝桥杯·c++20
小葡萄20253 个月前
黑马程序员2024新版C++笔记 第五章 面向对象
开发语言·c++·笔记·c++20
Tipriest_3 个月前
【C++20新特性】ranges::sort()使用方法,优势,注意点
算法·leetcode·c++20·排序·sort