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 ...
随机推荐
- java使用Runtime.exec()运行windwos dos或linux shell命令
使用Runtime.exec()运行windwos dos或linux shell命令,按实际情况具体测试 实例代码: package com.bookoo.test.command; imp ...
- MySql(八):MySQL性能调优——Query 的优化
一.理解MySQL的Query Optimizer MySQL Optimizer是一个专门负责优化SELECT 语句的优化器模块,它主要的功能就是通过计算分析系统中收集的各种统计信息,为客户端请求的 ...
- ubuntu16.04----jdk---install----config
1.下载jdk. 2.验证java是否安装,使用java -version命令,如下图所示说明没有安装: 3.在usr目录中创建一个jdk-8目录,如下图所示: 4.配置系统环境变量,编辑/etc/p ...
- 使用java+TestNG进行接口回归测试
TestNG是一个开源自动化测试框架,“NG”表示下一代(Next Generation的首字母). TestNG类似于JUnit(特别是JUnit 4),但它不是JUnit框架的扩展,相较于Juni ...
- sealed,new,virtual,abstract与override关键字的区别?
1. sealed——“断子绝孙” 密封类不能被继承.密封方法可以重写基类中的方法,但其本身不能在任何派生类中进一步重写.当应用于方法或属性时,sealed修饰符必须始终与override一起使用. ...
- ASP.NET页面间传值的几种方式
ASP.NET页面间传值的几种方式 1.使用QueryString 使用QuerySting在页面间传递值已经是一种很老的机制了,这种方法的主要优点是实现起来非常简单,然而它的缺点是传递的值是会显示在 ...
- C语言内存分配函数malloc——————【Badboy】
C语言中经常使用的内存分配函数有malloc.calloc和realloc等三个,当中.最经常使用的肯定是malloc,这里简单说一下这三者的差别和联系. 1.声明 这三个函数都在stdlib.h库文 ...
- OpenSUSE 13.1上安装StrongSwan
结果: 1)iOS 7.1设备能够拨IPSec VPN到StrongSwan电脑上面来 - Connect to VPN 2)iOS 设备浏览器能够訪问StrongSwan VPN所在的内网地址服务器 ...
- Docker入门系列8
commit docker commit -m "Added json gem" -a "Docker Newbee" 0b2616b0e5a8 ouruser ...
- android 关于ScrollView 的博客做记录学习
1.Android ScrollView向上滑动控件顶部悬浮效果实现 2.[android]仿知乎ScrollView滚动改变标题栏透明度 3.github开源Android组件资源整理(五)Scro ...