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++协程的实现方式总结的更多相关文章

  1. 物无定味适口者珍,Python3并发场景(CPU密集/IO密集)任务的并发方式的场景抉择(多线程threading/多进程multiprocessing/协程asyncio)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_221 一般情况下,大家对Python原生的并发/并行工作方式:进程.线程和协程的关系与区别都能讲清楚.甚至具体的对象名称.内置方法 ...

  2. Day11 线程、进程、协程

    创建线程第一种:import threadingdef f1(arg): print(arg) t = threading.Thread(target=f1, args=(123,))#t.start ...

  3. Python并发实践_02_通过yield实现协程

    python中实现并发的方式有很多种,通过多进程并发可以真正利用多核资源,而多线程并发则实现了进程内资源的共享,然而Python中由于GIL的存在,多线程是没有办法真正实现多核资源的. 对于计算密集型 ...

  4. python中的协程

    目录 协程是啥 协程和线程差异 简单实现协程 greenlet 安装方式 gevent 安装 1. gevent的使用 2. gevent切换执行 3. 给程序打补丁 进程.线程.协程对比 请仔细理解 ...

  5. Unity 协程使用指南

    0x00 前言 在使用Unity的过程中,对协程仅仅知道怎样使用,但并不知道协程的内部机理,对于自己不清楚的部分就像一块大石压力心里.让自己感觉到担忧和不适. 这篇文章一探到底,彻底揭开协程的面纱,让 ...

  6. Python 进阶 之 协程

    协程的概念级描述(与线程对比):转自知乎 链接 线程有两个必须要处理的问题:一是碰着阻塞式I\O会导致整个进程被挂起: 二是由于缺乏时钟阻塞,进程需要自己拥有调度线程的能力. 如果一种实现使得每个线程 ...

  7. IO多路复用、协程

    一.铺垫:基于socket发送http请求 1.需求一:向百度发送请求搜索关键字“alex”,有如下两种方式: import requests ret = requests.get('https:// ...

  8. 流畅python学习笔记:第十六章:协程

    通常在python进行编程一般都是使用多线程或者多进程来实现.这里介绍另外一种并发的方式,就是协程,但和多线程以及多进程不一样的是,协程是运行在单线程当中的并发.来看下具体的例子: def simpl ...

  9. PHP回顾之协程

    转载请注明文章出处: https://tlanyan.me/php-review... PHP回顾系列目录 PHP基础 web请求 cookie web响应 session 数据库操作 加解密 Com ...

随机推荐

  1. link标签的rel属性

    <link>标签定义了当前文档与 Web 集合中其他文档的关系.link 元素是一个空元素,它仅包含属性.此元素只能存在于 head 部分,不过它可出现任何次数.在 HTML 中,< ...

  2. 【Union Find】JAVA implementation

    import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Scan ...

  3. caffe-ubuntu1604-gtx850m-i7-4710hq----VGG_ILSVRC_16_layers.caffemodel

    c++调用vgg16: ./build/install/bin/classification \ /media/whale/wsWin10/wsCaffe/model-zoo/VGG16//deplo ...

  4. 利用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 ...

  5. FAT12中,如何定位大于一个扇区(512B)的文件内容

    [0]README 0.1)本文旨在于 演示在FAT12中, 如何取定位大于 512B 的文件内容,和查看它: 0.2)如何制作FAT12文件系统,以及如何向文件中添加temp.txt文件,参见: { ...

  6. ios --转载 使用SMSSDK实现短信验证:

    1.先到http://www.mob.com/#/网站注册账号,然后下载最新的sdk(有Android和iOS两个版本,根据需要进行下载) 2.进入到后台选择SecurityCodeSDk(支持全球短 ...

  7. java timer 指定某时间点执行

    package com.northeasttycoon.service; import java.util.Calendar;import java.util.Timer;import java.ut ...

  8. Sqlite 设置外键级联更新

    Sqlite 设置外键级联更新 选择好外键表和列以后,勾选更新事件,更新方式设置为CASCADE,即可在外键更新时自动更新

  9. intellij idea 大内存优化配置 idea64.exe.vmoptions文件配置

    -ea-server-Xms2G-Xmx4096M-Xss2m-XX:MaxMetaspaceSize=2G-XX:ReservedCodeCacheSize=1G-XX:MetaspaceSize= ...

  10. 九度OJ 1029:魔咒词典 (排序)

    时间限制:5 秒 内存限制:32 兆 特殊判题:否 提交:4574 解决:1318 题目描述:     哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部 ...