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

34、协程

在Linux系统中,协程是一种轻量级的线程,它们允许在多个任务之间切换,而不需要操作系统的线程调度。协程可以分为有栈协程和无栈协程,以及对称协程和非对称协程。

有栈协程

有栈协程每个协程都有自己的栈空间,允许协程在执行过程中保存局部变量和函数调用栈。切换协程时,保存和恢复整个栈的内容。

示例:

#include <ucontext.h>
#include <iostream>ucontext_t ctx_main, ctx_func;void func() {std::cout << "Inside coroutine\n";swapcontext(&ctx_func, &ctx_main);std::cout << "Back in coroutine\n";
}int main() {char stack[8192];getcontext(&ctx_func);ctx_func.uc_stack.ss_sp = stack;ctx_func.uc_stack.ss_size = sizeof(stack);ctx_func.uc_link = &ctx_main;makecontext(&ctx_func, func, 0);std::cout << "Starting coroutine\n";swapcontext(&ctx_main, &ctx_func);std::cout << "Back in main\n";swapcontext(&ctx_main, &ctx_func);std::cout << "Finished\n";return 0;
}

无栈协程

无栈协程不需要独立的栈空间,通常通过状态机实现。每次切换时,只保存和恢复必要的状态信息。

示例:

#include <iostream>class Coroutine {
public:Coroutine() : state(0) {}bool resume() {switch (state) {case 0:std::cout << "Inside coroutine\n";state = 1;return true;case 1:std::cout << "Back in coroutine\n";state = 2;return true;case 2:return false;}return false;}private:int state;
};int main() {Coroutine coro;std::cout << "Starting coroutine\n";while (coro.resume());std::cout << "Finished\n";return 0;
}

对称协程

对称协程允许协程之间相互调用和切换,没有主协程的概念。


非对称协程

非对称协程有一个主协程,其他协程只能返回到主协程,不能直接相互调用。


C++20的协程

C++20引入的协程是无栈协程,并且是非对称协程。它们通过编译器生成状态机来管理协程的状态。

示例:

#include <coroutine>
#include <iostream>struct ReturnObject {struct promise_type {ReturnObject get_return_object() { return {}; }std::suspend_never initial_suspend() { return {}; }std::suspend_never final_suspend() noexcept { return {}; }void return_void() {}void unhandled_exception() {}};
};ReturnObject foo() {std::cout << "Inside coroutine\n";co_await std::suspend_always{};std::cout << "Back in coroutine\n";
}int main() {auto coro = foo();std::cout << "Starting coroutine\n";coro.resume();std::cout << "Finished\n";return 0;
}
http://www.lryc.cn/news/2404755.html

相关文章:

  • Apache POI操作Excel详解
  • Docker容器部署elasticsearch8.*与Kibana8.*版本使用filebeat采集日志
  • OpenCV CUDA模块图像处理------双边滤波的GPU版本函数bilateralFilter()
  • 华为手机开机卡在Huawei界面不动怎么办?
  • 并行硬件环境及并行编程
  • ORM框架(SQLAlchemy 与 Tortoise )
  • go语言map扩容
  • 安全访问家中 Linux 服务器的远程方案 —— 专为单用户场景设计
  • 前端开发三剑客:HTML5+CSS3+ES6
  • [Java 基础]Java 中的关键字
  • 5.3 Spring Boot整合JPA
  • 腾讯开源视频生成工具 HunyuanVideo-Avatar,上传一张图+一段音频,就能让图中的人物、动物甚至虚拟角色“活”过来,开口说话、唱歌、演相声!
  • [文献阅读] Emo-VITS - An Emotion Speech Synthesis Method Based on VITS
  • 网络协议通俗易懂详解指南
  • OpenCV-Python Tutorial : A Candy from Official Main Page(持续更新)
  • 【Vue】指令补充+样式绑定+计算属性+侦听器
  • .Net Framework 4/C# 泛型的使用、迭代器和分部类
  • LLM 笔记:Speculative Decoding 投机采样
  • 当SAP系统内计划订单转换为生产订单时发生了什么?
  • PDF转PPT转换方法总结
  • 3D Web轻量化引擎HOOPS Communicator的定制化能力全面解析
  • 【力扣链表篇】19.删除链表的倒数第N个节点
  • .Net Framework 4/C# 集合和索引器
  • 如何使用Jmeter进行压力测试?
  • Grafana-ECharts应用讲解(玫瑰图示例)
  • 洛谷P1591阶乘数码
  • 前端vue3 上传/导入文件 调用接口
  • 概述侧边导航的作用与价值
  • Python训练营-Day22-Titanic - Machine Learning from Disaster
  • FreeCAD:开源世界的三维建模利器