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 ...
随机推荐
- link标签的rel属性
<link>标签定义了当前文档与 Web 集合中其他文档的关系.link 元素是一个空元素,它仅包含属性.此元素只能存在于 head 部分,不过它可出现任何次数.在 HTML 中,< ...
- 【Union Find】JAVA implementation
import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Scan ...
- caffe-ubuntu1604-gtx850m-i7-4710hq----VGG_ILSVRC_16_layers.caffemodel
c++调用vgg16: ./build/install/bin/classification \ /media/whale/wsWin10/wsCaffe/model-zoo/VGG16//deplo ...
- 利用GROUP_CONCAT函数把相同信息的合并到同一个字段中
SELECT a.*,GROUP_CONCAT(b.pri_name) FROM sh_role a LEFT JOIN sh_privilege b ON FIND_IN_SET(b.id,a.pr ...
- FAT12中,如何定位大于一个扇区(512B)的文件内容
[0]README 0.1)本文旨在于 演示在FAT12中, 如何取定位大于 512B 的文件内容,和查看它: 0.2)如何制作FAT12文件系统,以及如何向文件中添加temp.txt文件,参见: { ...
- ios --转载 使用SMSSDK实现短信验证:
1.先到http://www.mob.com/#/网站注册账号,然后下载最新的sdk(有Android和iOS两个版本,根据需要进行下载) 2.进入到后台选择SecurityCodeSDk(支持全球短 ...
- java timer 指定某时间点执行
package com.northeasttycoon.service; import java.util.Calendar;import java.util.Timer;import java.ut ...
- Sqlite 设置外键级联更新
Sqlite 设置外键级联更新 选择好外键表和列以后,勾选更新事件,更新方式设置为CASCADE,即可在外键更新时自动更新
- intellij idea 大内存优化配置 idea64.exe.vmoptions文件配置
-ea-server-Xms2G-Xmx4096M-Xss2m-XX:MaxMetaspaceSize=2G-XX:ReservedCodeCacheSize=1G-XX:MetaspaceSize= ...
- 九度OJ 1029:魔咒词典 (排序)
时间限制:5 秒 内存限制:32 兆 特殊判题:否 提交:4574 解决:1318 题目描述: 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部 ...