C/C++协程的实现方式总结
1、利用 C 语言的 setjmp 和 longjmp,函数中使用 static local 的变量来保存协程内部的数据。
函数原型:int setjmp(jmp_buf envbuf);
void longjmp(jmp_buf envbuf, int val);
先调用setjmp,用变量envbuf记录当前的位置,然后调用longjmp,返回envbuf所记录的位置,并使setjmp的返回值为val。使用longjmp后,envbuf的内容会被销毁。
一个例子(引自《C专家编程》):
#include <stdio.h>
#include <setjmp.h> jmp_buf buf; banana()
{
printf("in banana() \n");
longjmp(buf,);
printf("you'll never see this,because i longjmp'd");
} main()
{
if(setjmp(buf))
printf("back in main\n");
else
{
printf("first time through\n");
banana();
}
}
打印结果:
first time through
in banana()
back in main
2、利用C语言语法switch-case的技巧来实现(Protothreads) 。
设置一个标识符,改变标识符的值,通过switch-case对标识符值的判断操纵各协程函数轮流执行。
每个协程函数可配一个结构体,保存栈内容和状态机。
代码:https://github.com/georgeredinger/protothreads
3、使用汇编代码来切换上下文(实现c协程) 。
构建一个结构体保存栈内容和当前位置等上下文信息,利用汇编语言的跳转实现协程功能。
详情见:https://www.cnblogs.com/heluan/p/9899824.html
4、利用操作系统提供的接口:Linux的ucontext,Windows的Fiber。(云风的coroutine)
ucontext: makecontext() 创建上下文
getcontext() 读取上下文
setcontext() 设置上下文
swapcontext() 跳转上下文
Fiber(纤程):ConverThreadToFiber() 从当前线程进入纤程
CreateFiber() 创建新纤程
SwitchToFiber() 切换到纤程
DeleteFiber() 删除纤程
如果删除当前纤程,会导致它所在的线程退出
操作系统的接口函数本身,提供了保存栈内容的功能。
C/C++协程的实现方式总结的更多相关文章
- 物无定味适口者珍,Python3并发场景(CPU密集/IO密集)任务的并发方式的场景抉择(多线程threading/多进程multiprocessing/协程asyncio)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_221 一般情况下,大家对Python原生的并发/并行工作方式:进程.线程和协程的关系与区别都能讲清楚.甚至具体的对象名称.内置方法 ...
- Day11 线程、进程、协程
创建线程第一种:import threadingdef f1(arg): print(arg) t = threading.Thread(target=f1, args=(123,))#t.start ...
- Python并发实践_02_通过yield实现协程
python中实现并发的方式有很多种,通过多进程并发可以真正利用多核资源,而多线程并发则实现了进程内资源的共享,然而Python中由于GIL的存在,多线程是没有办法真正实现多核资源的. 对于计算密集型 ...
- python中的协程
目录 协程是啥 协程和线程差异 简单实现协程 greenlet 安装方式 gevent 安装 1. gevent的使用 2. gevent切换执行 3. 给程序打补丁 进程.线程.协程对比 请仔细理解 ...
- Unity 协程使用指南
0x00 前言 在使用Unity的过程中,对协程仅仅知道怎样使用,但并不知道协程的内部机理,对于自己不清楚的部分就像一块大石压力心里.让自己感觉到担忧和不适. 这篇文章一探到底,彻底揭开协程的面纱,让 ...
- Python 进阶 之 协程
协程的概念级描述(与线程对比):转自知乎 链接 线程有两个必须要处理的问题:一是碰着阻塞式I\O会导致整个进程被挂起: 二是由于缺乏时钟阻塞,进程需要自己拥有调度线程的能力. 如果一种实现使得每个线程 ...
- IO多路复用、协程
一.铺垫:基于socket发送http请求 1.需求一:向百度发送请求搜索关键字“alex”,有如下两种方式: import requests ret = requests.get('https:// ...
- 流畅python学习笔记:第十六章:协程
通常在python进行编程一般都是使用多线程或者多进程来实现.这里介绍另外一种并发的方式,就是协程,但和多线程以及多进程不一样的是,协程是运行在单线程当中的并发.来看下具体的例子: def simpl ...
- PHP回顾之协程
转载请注明文章出处: https://tlanyan.me/php-review... PHP回顾系列目录 PHP基础 web请求 cookie web响应 session 数据库操作 加解密 Com ...
随机推荐
- 对于Json和对象转换的学习
学习这个的用处有非常多的: 在传输数据过程中比較查看数据比較清晰,代码也较清晰.也能够避免split函数带来的隐藏bug 当然也有不足: 准备工具较繁琐,须要准备对象(当然 ...
- Netty(三):线程模型
Netty中支持单线程模型,多线程模型,主从多线程模型. 1 单线程模型 在ServerBootstrap调用方法group的时候,传递的参数是同一个线程组,且在构造线程组的时候,构造参数为1,这种开 ...
- 开发ActiveX控件调用另一个ActiveX系列2——调试ActiveX
关于调试ActiveX控件,有若干方法,例如可以建一个MFC工程调用调试,我则倾向于使用附加到浏览器进程,因为浏览器才是真正运行的环境. 打开加载ActiveX的目标页面,当然希望我们的调试内容不是自 ...
- mybatis的两种分页方式:RowBounds和PageHelper
原理:拦截器. 使用方法: RowBounds:在mapper.java中的方法中传入RowBounds对象. RowBounds rowBounds = new RowBounds(offset, ...
- 时间控件(DateTime Picker)
中文:http://www.bootcss.com/p/bootstrap-datetimepicker/index.htm http://www.malot.fr/bootstrap-datetim ...
- LINUX线程初探
LINUX程序设计最重要的当然是进程与线程.本文主要以uart程序结合键盘输入控制uart的传输. 硬件平台:树莓派B+ 软件平台:raspberry 须要工具:USB转TTL(PL2303)+ ...
- Intellj IDEA光标替insert状态,back键无法删除内容
Intellj IDEA光标为insert状态,无法删除内容导入项目后,发现打开java文件的光标是win系统下按了insert键后的那种宽的光标,并且还无法删除内容,且按删除(delete)键也只见 ...
- 微信小程序TabBar的使用
一.TabBar使用步骤 1.创建所需要的界面和所需要的图片: 2.配置文件: 我们找到项目根目录中的配置文件 app.json 加入如下配置信息 "tabBar": { &quo ...
- C#中GroupBox控件的使用(转)
GroupBox(框架)控件是C#中用来组织其他控件形成一个控件组,它的使用方法为[工具箱]->[所有Windows窗体](或者是[容器]列表中)->[GroupBox],拖拽到窗体界面中 ...
- ubuntu nohup命令用法
让程序在后台运行 该命令的一般形式nohup command & 程序在后台运行并打印日志 nohup ./china_fund.py > china_fund.file 2>&a ...