c++有顺序的嵌套函数的协程(无返回值)解决方案1
·
#include <iostream> // 输入输出流
#include <functional> // 函数对象相关
#include <thread> // 多线程支持
#include <chrono> // 时间库
#include <coroutine> // C++20 协程核心
#include <atomic> // 原子操作
#include <memory> // 智能指针
class IntReader
{
public:
// 协程等待时是否立即准备好
bool await_ready()
{
return false; // 返回 false 表示需要挂起,等待异步操作
};
// 协程挂起时调用的函数
void await_suspend(std::coroutine_handle<> handle)
{
// 创建新线程执行异步操作
std::thread thread(
[this, handle]() // 捕获当前对象和协程句柄
{
// 模拟耗时操作(如网络请求)
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
value_ = 1; // 设置结果值
handle.resume(); // 恢复协程执行
}
);
thread.detach(); // 分离线程,让其独立运行
}
// 协程恢复时返回的结果
int await_resume()
{
return value_; // 返回异步操作的结果
}
private:
int value_{}; // 存储异步操作的结果
};
class Task
{
public:
// promise_type是协程机制要求的内部类,用于控制协程行为
class promise_type
{
public:
// 创建协程的返回对象
Task get_return_object() { return{}; } // 返回默认构造的Task对象
// 控制协程开始时的行为
std::suspend_never initial_suspend() { return{}; } // 立即执行,不挂起
// 控制协程结束时的行为
std::suspend_never final_suspend()noexcept { return{}; } // 立即销毁,不挂起
// 异常处理函数
void unhandled_exception() {} // 空实现,异常会导致程序终止
// 处理co_return void的情况
void return_void() {} // co_return; 时调用
};
};
Task GetInt() // 返回Task类型的协程
{
IntReader reader1; // 创建第一个可等待对象
int total = co_await reader1; // 等待第一个异步操作完成
std::cout << "reader1:" << total << std::endl; // 输出结果
IntReader reader2; // 创建第二个可等待对象
total += co_await reader2; // 等待并累加结果
std::cout << "reader2:" << total << std::endl;
IntReader reader3; // 创建第三个可等待对象
total += co_await reader3; // 等待并累加结果
std::cout << "reader3:" << total << std::endl;
co_return; // 返回最终结果
}
int main()
{
Task task = GetInt(); // 调用协程函数,返回Task对象
// 此时协程已经开始执行,但由于有异步操作,可能还没完成
std::string line;
while (std::cin >> line) // 循环读取用户输入
{
// 每次输入后检查并输出协程的当前结果
std::cout << "main:" << line << std::endl;
}
return 0;
}
//
//代码执行流程详解
//main函数启动 → 调用 GetInt() 协程
//
//协程开始执行 → 创建 IntReader reader1
//
//遇到 co_await reader1 → 调用 reader1.await_ready() (返回false)
//
//调用 reader1.await_suspend() → 启动新线程,挂起协程
//
//主线程继续 → 进入while循环等待用户输入
//
//异步线程运行 → 睡眠1秒后设置 value_ = 1,调用 handle.resume()
//
//协程恢复执行 → 调用 reader1.await_resume() 获取结果,输出 "reader1:1"
//
//重复步骤2 - 7 → 处理 reader2 和 reader3
//
//最终输出 → "reader3:3"
//
//协程结束 → 调用 co_return,协程销毁
//
//存在的问题
//线程安全问题:多个线程同时访问 IntReader::value_,存在数据竞争
//
//生命周期问题:IntReader 对象在异步操作完成前可能被销毁
//
//竞态条件:主线程可能在异步线程设置值之前读取值
//
//缺少错误处理:异常会导致程序终止
更多推荐
所有评论(0)