windows 纤程(fiber) 实现的协程
来源:互联网 发布:单片机 usb 虚拟串口 编辑:程序博客网 时间:2024/06/04 23:27
参考云风的协程库实现:https://github.com/cloudwu/coroutine
云风的协程为 非对称的共享栈协程
以下为fiber实现的非对称协程:
环境:win7、VS2013
头文件: (coroutine.h)
#ifndef __COROUTINE__H__#define __COROUTINE__H__#define COROUTINE_DEAD 0#define COROUTINE_READY 1#define COROUTINE_RUNNING 2#define COROUTINE_SUSPEND 3typedef struct schedule schedule;typedef void(*coroutine_func)(schedule *s, void *ud);schedule *coroutine_open();void coroutine_close(schedule *s);int coroutine_new(schedule *s, coroutine_func *, void *ud);void coroutine_resume(schedule *s, int id);void coroutine_yield(schedule *s);int coroutine_status(schedule *s, int id);int coroutine_running(schedule *s);#endif
源文件:(coroutine.c)
#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <assert.h>#include "coroutine.h"/* windows fiber版本的协程yield的时候直接切换到主协程(main),而不是swapcontext的切换到上次运行协程,但最后达到的结果却一样*/// 默认容量#define DEFAULT_CAP 8// 堆栈大小#define INIT_STACK 1048576 //(1024*1024)typedef struct schedule schedule;typedef struct coroutine coroutine;typedef struct coroutine_para coroutine_para;struct schedule{int cap; // 容量int conums;int curID; // 当前协程IDLPVOID main;coroutine **co;};struct coroutine{schedule *s;void *ud;int status;LPVOID ctx;coroutine_func func;};static int co_putin(schedule *s, coroutine *co){if (s->conums >= s->cap){int id = s->cap;s->co = realloc(s->co, sizeof(coroutine *) * s->cap * 2);memset(&s->co[s->cap], 0, sizeof(coroutine *) * s->cap);s->co[s->cap] = co;s->cap *= 2;++s->conums;return id;}else{for (int i = 0; i < s->cap; i++){int id = (i + s->conums) % s->cap;if (s->co[id] == NULL){s->co[id] = co;++s->conums;return id;}}}assert(0);return -1;}static void co_delete(coroutine *co){//If the currently running fiber calls DeleteFiber, its thread calls ExitThread and terminates. //However, if a currently running fiber is deleted by another fiber, the thread running the //deleted fiber is likely to terminate abnormally because the fiber stack has been freed.DeleteFiber(co->ctx);free(co);}schedule *coroutine_open(){schedule *s = malloc(sizeof(schedule));s->cap = DEFAULT_CAP;s->conums = 0;s->curID = -1;s->co = malloc(sizeof(coroutine *) * s->cap);memset(s->co, 0, sizeof(coroutine *) * s->cap);s->main = ConvertThreadToFiberEx(NULL, FIBER_FLAG_FLOAT_SWITCH);return s;}void coroutine_close(schedule *s){for (int i = 0; i < s->cap; i++){coroutine *co = s->co[i];if (co) co_delete(co);}free(s->co);s->co = NULL;free(s);}void __stdcall coroutine_main(LPVOID lpParameter){schedule* s = (schedule*)lpParameter;int id = s->curID;coroutine *co = s->co[id];(co->func)(s, co->ud);s->curID = -1;--s->conums;s->co[id] = NULL;//co_delete(co);SwitchToFiber(s->main);}int coroutine_new(schedule *s, coroutine_func *func, void *ud){coroutine *co = malloc(sizeof(coroutine));co->s = s;co->status = COROUTINE_READY;co->func = func;co->ud = ud;int id = co_putin(s, co);co->ctx = CreateFiberEx(INIT_STACK, 0, FIBER_FLAG_FLOAT_SWITCH, coroutine_main, s);co->status = COROUTINE_READY;return id;}void coroutine_resume(schedule *s, int id){assert(id >= 0 && id < s->cap);if (id < 0 || id >= s->cap) return;coroutine *co = s->co[id];if (co == NULL) return;switch (co->status){case COROUTINE_READY:case COROUTINE_SUSPEND:co->status = COROUTINE_RUNNING;s->curID = id;SwitchToFiber(co->ctx);if (!s->co[id]) co_delete(co);break;default:assert(0);break;}}void coroutine_yield(schedule *s){int id = s->curID;assert(id >= 0 && id < s->cap);if (id < 0) return;coroutine *co = s->co[id];co->status = COROUTINE_SUSPEND;s->curID = -1;SwitchToFiber(s->main);}int coroutine_status(schedule *s, int id){assert(id >= 0 && id < s->cap);if (id < 0) return;if (s->co[id] == NULL) {return COROUTINE_DEAD;}return s->co[id]->status;}int coroutine_running(schedule *s){return s->curID;}
测试程序:(main.c)
#include "coroutine.h"void test3(schedule *s, void *ud){int *data = (int*)ud;for (int i = 0; i < 3; i++){printf("test3 i=%d\n",i);coroutine_yield(s);printf("yield co id = %d.\n", *data);}}void coroutine_test(){printf("coroutine_test3 begin\n");schedule *s = coroutine_open();int a = 11;int id1 = coroutine_new(s, test3, &a);int id2 = coroutine_new(s, test3, &a);while (coroutine_status(s, id1) && coroutine_status(s, id2)){printf("\nresume co id = %d.\n",id1);coroutine_resume(s, id1);//printf("resume co id = %d.\n", id2);//coroutine_resume(s, id2);}int id3 = coroutine_new(s, test3, &a);while (coroutine_status(s, id3)){printf("\nresume co id = %d.\n", id3);coroutine_resume(s, id3);}printf("coroutine_test3 end\n");coroutine_close(s);}int main(){coroutine_test();return 0;}
0 0
- windows 纤程(fiber) 实现的协程
- Windows的纤程(Fiber)
- 纤程(Fiber)的用法介绍
- Fiber 纤程
- Windows Via C/C++ 读书笔记 8 Fiber(纤程)
- Ruby Fiber的教程
- 纤程(Fiber)
- Thread(线程)、Fiber(纤程)、coroutine(协程) 之间的区别以及...
- Java协程框架--Kilim框架Fiber浅析
- Java协程框架--Kilim框架Fiber浅析
- 《Windows via C/C++》学习笔记 —— 纤程(Fiber)
- 纤程(Fiber)(转帖)
- Coroutine in Java - Quasar Fiber实现-优
- 术语:纤程(fiber)不是轻量级线程
- 异步通讯中使用纤程(Fiber/UserSpaceThread)
- Fiber 是什么?
- Google Fiber是自Gmail以来最具颠覆性的产品
- 谷歌放弃试验6年的超级宽带计划:Google Fiber面临出售
- 解决金山词霸2010牛津旗舰版破解词典丢失的方法
- for循环
- Struts1 NESTED标签
- SpringMVC创建web项目基础之(二)——Spring MVC与Mybatis整合详解
- Java基础-网络编程(二)
- windows 纤程(fiber) 实现的协程
- 网页下载器urllib2简介
- Problem 2 交错和查询
- Android-WindowManger的应用
- 汽车维修问题多 别被维修店潜规则忽悠了
- 关于Class.getResource和ClassLoader.getResource的路径问题
- java集合框架
- 2017.1.14——寒假集训第三天
- 微信小程序页面间的跳转