简单的协程
#include <iostream> // 包含标准输入输出流头文件
#include <thread> // 包含线程支持头文件
#include <coroutine> // 包含协程支持头文件
#include <future> // 包含异步操作支持头文件
#include <chrono> // 包含时间库头文件
#include <functional> // 包含函数对象头文件
// 定义一个名为 Result 的结构体
struct Result{
// 定义一个 promise_type 结构体
struct promise_type {
// 返回一个 Result 对象
Result get_return_object() { return {}; }
// 定义协程的初始挂起点
std::suspend_never initial_suspend() { return {}; }
// 定义协程的最终挂起点
std::suspend_never final_suspend() noexcept { return {}; }
// 协程的返回值类型为 void
void return_void() {}
// 未处理的异常处理函数
void unhandled_exception() {}
};
};
// 定义一个全局的协程句柄
std::coroutine_handle<> coroutine_handle;
// 定义一个可等待对象结构体
struct AWaitableObject
{
// 默认构造函数
AWaitableObject() {}
// 定义 await_ready 函数,表示是否准备好
bool await_ready() const { return false; }
// 定义 await_resume 函数,表示恢复时的返回值
int await_resume() { return 0; }
// 定义 await_suspend 函数,表示挂起协程时的操作
void await_suspend(std::coroutine_handle<> handle){
// 保存协程句柄
coroutine_handle = handle;
}
};
// 定义一个协程函数
Result CoroutineFunction()
{
// 打印开始协程的信息
std::cout << "start coroutine\n";
// 等待可等待对象
int ret = co_await AWaitableObject();
// 打印完成协程的信息
std::cout << "finish coroutine\n";
}
// 主函数
int main()
{
// 打印开始的信息
std::cout << "start \n";
// 调用协程函数
auto coro = CoroutineFunction();
// 打印协程 co_await 的信息
std::cout << "coroutine co_await\n";
// 恢复协程
coroutine_handle.resume();
// 返回 0 表示程序正常结束
return 0;
}
co_await
是 C++20 引入的一种新的操作符,用于支持协程的异步等待。co_await
操作符的使用需要等待一个可等待对象,该对象需要实现三个特定的成员函数或通过重载对应的操作符。这三个成员函数分别是 await_ready()
, await_suspend()
, 和 await_resume()
。我们来看一下在你的代码中 co_await AWaitableObject()
是如何工作的:
-
await_ready
:bool await_ready() const { return false; }
- 这个函数返回一个布尔值,表示这个对象是否已经准备好。如果返回
true
,协程将不会被挂起,直接继续执行后续代码。如果返回false
,协程将被挂起,直到这个对象准备好。 - 在你的代码中,
await_ready
总是返回false
,所以协程会被挂起。
- 这个函数返回一个布尔值,表示这个对象是否已经准备好。如果返回
-
await_suspend
:void await_suspend(std::coroutine_handle<> handle) { coroutine_handle = handle; }
- 这个函数在协程被挂起时被调用。它接受一个
std::coroutine_handle
作为参数,表示当前协程的句柄。 - 在你的代码中,它将协程句柄保存到全局变量
coroutine_handle
中。这允许你在以后手动恢复这个协程。
- 这个函数在协程被挂起时被调用。它接受一个
-
await_resume
:int await_resume() { return 0; }
- 这个函数在协程恢复时被调用。它的返回值将成为
co_await
表达式的结果。 - 在你的代码中,它返回
0
。
- 这个函数在协程恢复时被调用。它的返回值将成为
现在我们具体来看 co_await AWaitableObject();
在你的代码中的执行流程:
-
进入
CoroutineFunction
函数:std::cout << "start coroutine\n";
- 打印 “start coroutine”。
-
执行
co_await AWaitableObject()
:- 创建一个
AWaitableObject
对象。 - 调用
AWaitableObject
的await_ready
方法,返回false
,因此协程挂起。 - 调用
AWaitableObject
的await_suspend
方法,将协程句柄保存到全局变量coroutine_handle
中。 - 协程挂起,控制权返回到调用方
main
函数。
- 创建一个
-
回到
main
函数:std::cout << "coroutine co_await\n";
- 打印 “coroutine co_await”。
-
恢复协程:
coroutine_handle.resume();
- 手动恢复协程,调用
await_resume
方法,返回0
。
- 手动恢复协程,调用
-
继续执行
CoroutineFunction
:std::cout << "finish coroutine\n";
- 打印 “finish coroutine”。
整个过程展示了协程的挂起和恢复机制,通过 co_await
实现异步操作。AWaitableObject
作为一个可等待对象,实现了协程所需的三个成员函数,协调了协程的挂起和恢复。
多个任务
#include <chrono>
#include <coroutine>
#include <deque>
#include <iostream>
#include <windows.h>
std::deque<std::coroutine_handle<>> tasks;
// 简单的协程类
struct AsyncTask {
struct promise_type {
AsyncTask get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
struct AWaitableObject {
int delay;
AWaitableObject(int delay) : delay(delay) {}
bool await_ready() const { return false; }
int await_resume() { return 0; }
void await_suspend(std::coroutine_handle<> handle) {
tasks.push_back(handle);
Sleep(delay);
}
};
// 模拟异步任务1
AsyncTask task1() {
co_await AWaitableObject(200);
std::cout << "Task 1 completed" << std::endl;
}
// 模拟异步任务2
AsyncTask task2() {
co_await AWaitableObject(100);
std::cout << "Task 2 completed" << std::endl;
}
// 主函数
int main() {
// 打印开始的信息
std::cout << "main start \n";
task1();
task2();
std::cout << "main continue\n";
// 恢复协程
while (!tasks.empty()) {
auto task = tasks.front();
tasks.pop_front();
task.resume();
}
std::cout << "main completed" << std::endl;
return 0;
}
推荐资料:
深入浅出c++协程
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » C++协程
发表评论 取消回复