当前位置: 首页 > news >正文

C++20协程异步

code
#include <coroutine>
#include <future>
#include <iostream>
#include "QApplication.h"/** 自定义协程等待体*/
struct MyWaiter {int value;constexpr bool await_ready() const noexcept{std::cout << "Step 5\n";return false; // true=准备好了不挂起,false=挂起}bool await_suspend(std::coroutine_handle<> handle){ // 协程挂起时调用// 切换线程std::cout << "Step 6\n";std::async([=] {std::cout << "Step 7\n";std::this_thread::sleep_for(std::chrono::seconds(1));handle.resume(); // 延迟1s后恢复协程});std::cout << "Step 11\n";return true; // 挂起}int await_resume(){ // 协程恢复时调用std::cout << "Step 8\n";return value;}
};/** 自定义返回值* 需要开发者自行保证协程在挂起后续恢复执行时参数引用或者指针指向的对象仍然存活**/
struct GenIntIter {struct promise_type {int value_;promise_type(){std::cout << "Step 1\n";}GenIntIter get_return_object(){std::cout << "Step 2\n";return GenIntIter { *this };}static GenIntIter get_return_object_on_allocation_failure(){ // new 分配失败promise_type result;result.value_ = -1;return GenIntIter(result);}auto initial_suspend() const noexcept{ // 运行前std::cout << "Step 3\n";return std::suspend_never {}; // 挂起//            return MyWaiter { .value = value_ };}auto final_suspend() const noexcept{ // 析构前std::cout << "Step 10\n";// 如果在 final_suspend 那里停下,手动调用 coro.destroy(),不然就会漏内存// 如果已经final_suspend了,再coro.destroy()会seg faultreturn std::suspend_always {}; // 挂起//            return std::suspend_never {}; // 不挂起}auto yield_value(int value){value_ = value;return std::suspend_always {}; // 挂起}void return_value(int value){value_ = value;}void unhandled_exception(){std::terminate();}};explicit GenIntIter(promise_type& p): handle_(std::coroutine_handle<promise_type>::from_promise(p)){}~GenIntIter(){if (handle_ && !handle_.done())handle_.destroy();}int next(){if (!handle_ || handle_.done())return -1;handle_();return handle_.promise().value_;}int val(){return handle_.promise().value_;}std::coroutine_handle<promise_type> handle_;
};// 协程函数
GenIntIter foo()
{for (int i = 0; i < 10; ++i) {co_yield i;}co_return -1;
}int work()
{return 5;
}// 线程异步
void thread()
{auto n = std::async(work);n.wait();
}// 协程异步
GenIntIter corioutine(int val)
{std::cout << "Step 4\n";auto n = co_await MyWaiter { .value = val };std::cout << "Step 9\n";co_return n;
}int main(int argc, char** argv)
{corioutine(5);std::cout << "Step 12\n";// 当 caller 调用一个协程的时候会先创建一个协程帧// 协程帧会构建 promise 对象,// 再通过 promise对象产生 return object。auto handle = foo();do {handle.val();} while (-1 != handle.next());QApplication app(argc, argv);return app.run;
}
参考

https://zhuanlan.zhihu.com/p/657993277

https://github.com/tearshark/librf

https://github.com/naasking/async.h

https://github.com/xiaoliang314/libatask/tree/master/lib

http://www.xdnf.cn/news/1181701.html

相关文章:

  • 论文Review Registration TEASER | TRO | MIT出品,点云配准经典BenchMark | 硬核的数学长文
  • 蜘蛛强引的原理与百度SEO的关系
  • Qt(资源库和按钮组)
  • SpringBoot+AI+Web3实战指南
  • pytest官方Tutorial所有示例详解(一)
  • 洛谷刷题7.24
  • 优选算法:移动零
  • 计算机网络知识点总结 (2)
  • go语言基础教程:1. Go 下载安装和设置
  • Java网络编程入门:从基础原理到实践(二)
  • 算法第三十八天:动态规划part06(第九章)
  • uboot FPGA调试环境搭建
  • io_uring:Linux异步I/O的革命性突破
  • 星慈光编程虫2号小车讲解第四篇--触摸按键
  • 平时遇到的错误码及场景?404?400?502?都是什么场景下什么含义,该怎么做 ?
  • vue3核心语法
  • (进阶向)Python第十四期OpenCv图像预处理方法[2]
  • 跨境支付入门~国际支付结算(稳定币)
  • 深度分析Java多线程机制
  • AI实践:Pydantic
  • Spring之SSM整合流程详解(Spring+SpringMVC+MyBatis)
  • 【Linux】常用命令(一)
  • 洛谷P1512 伊甸园日历游戏
  • SQL基础⑫ | 视图篇
  • C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(三)
  • 基于深度学习的图像分类:使用MobileNet实现高效分类
  • Python进阶第三方库之Matplotlib
  • 深度学习(鱼书)day01--感知机
  • LeetCode 23:合并 K 个升序链表
  • 【C++】使用中值滤波算法过滤数据样本中的尖刺噪声