当前位置: 首页 > 工具软件 > Coroutine > 使用案例 >

C++ coroutine 简单的例子

陆高峰
2023-12-01
#include <iostream>
#include <thread>
#include <coroutine>
#include <chrono>
#include <functional>

// g++-10 -std=c++2a coroutineDemo.cpp -fcoroutines -lpthread

using call_back = std::function<void(int)>;
void Add100ByCallback(int init, call_back f) // 异步调用
{
	std::thread t([init, f]() {
		std::this_thread::sleep_for(std::chrono::seconds(5));
		f(init + 100);
		});
	t.detach();
}

struct Add100AWaitable
{
	Add100AWaitable(int init) :init_(init) {}
	bool await_ready() const { return false; }
	int await_resume() { return result_; }
	void await_suspend(std::coroutine_handle<> handle)
	{
		auto f = [handle, this](int value) mutable {
			result_ = value;
			handle.resume();
		};
		Add100ByCallback(init_, f); // 调用原来的异步调用
	}
	int init_;
	int result_;
};

struct Task
{
	struct promise_type {
		auto get_return_object() { return Task{}; }
		auto initial_suspend() { return std::suspend_never{}; }
		auto final_suspend() noexcept { return std::suspend_never{}; }
		void unhandled_exception() { std::terminate(); }
		void return_void() {}
	};
};

Task Add100ByCoroutine(int init, call_back f)
{
	int ret = co_await Add100AWaitable(init);
	ret = co_await Add100AWaitable(ret);
	ret = co_await Add100AWaitable(ret);
	f(ret);
}

int main()
{
	Add100ByCoroutine(10, [](int value) { std::cout << "get result from coroutine1: " << value << "\n"; });
	Add100ByCoroutine(20, [](int value) { std::cout << "get result from coroutine2: " << value << "\n"; });
	Add100ByCoroutine(30, [](int value) { std::cout << "get result from coroutine3: " << value << "\n"; });
	Add100ByCoroutine(40, [](int value) { std::cout << "get result from coroutine4: " << value << "\n"; });
}

如果要实现形如co_await blabla;的协程调用格式, blabla就必须实现Awaitable。co_await是一个新的运算符。Awaitable主要有3个函数:
1. await_ready:返回Awaitable实例是否已经ready。协程开始会调用此函数,如果返回true,表示你想得到的结果已经得到了,协程不需要执行了。所以大部分情况这个函数的实现是要return false。
2. await_suspend:挂起awaitable。该函数会传入一个coroutine_handle类型的参数。这是一个由编译器生成的变量。在此函数中调用handle.resume(),就可以恢复协程。
3. await_resume:当协程重新运行时,会调用该函数。这个函数的返回值就是co_await运算符的返回值。

文章引用:c++20协程入门 - 知乎

代码我进行了修正和改进。

有问题,可以一起交流。

 类似资料: