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;

}

相关推荐
楼田莉子2 天前
C++20新特性:协程
开发语言·c++·后端·学习·c++20
ouliten4 天前
C++笔记:C++20风格线程池
c++·笔记·c++20
眠りたいです6 天前
现代C++:C++17中的新库特性
开发语言·c++·c++20·c++17
楼田莉子12 天前
C++20新特性:Range库
开发语言·c++·后端·学习·c++20
楼田莉子13 天前
C++20现代特性:概念与约束
开发语言·c++·后端·学习·c++20
aluluka13 天前
C++ 20 协程的探索
c++·c++20
君鼎17 天前
内存池完整实现——C++20版
c++20·内存池
普通网友1 个月前
记录我适配iOS26遇到的一些问题
c++20
前进吧-程序员1 个月前
C++20/23 Ranges:从「迭代器对」到「可组合管道」
c++20
Shan12051 个月前
实例分析:C++20的std::jthread
c++20