zoukankan      html  css  js  c++  java
  • 协程库的一些笔记

    由于协程的优点,所以协程库如今有好多libtask,boost::coroutine,libco......
     libtask
    非常不错,以后也许会用。
     boost我个人基本非常少用。
     腾讯的libco自己用汇编实现了swapcontext函数,不明觉厉(libtask也有ASM)。并且把epoll整合在了里面。
     微信后台就用到了它.在chinaunix.net上的一个帖子中就说到了这个。只是暂不适合我。

       还好云风实现过一个coroutine库,用的context系列函数,非常静止的封装,代码量非常小, 也没附加啥其他特性。用来加深理解再好只是。

    http://blog.codingnow.com/2012/07/c_coroutine.html 上有其相关说明。

    只是代码没凝视啥的,为了怕忘记一些体会,我按个人理解加了代码凝视, 在上Github上保存了一份. 

    https://github.com/xcltapestry/coroutine  (理解不深,如有错误欢迎指正). 


    至于以下是针对这个库的一些点,记录一下. 

    1. 结构体schedule与coroutine的參数意义 

    struct schedule { 
    	char stack[STACK_SIZE]; //执行时,co上下文用的就是这块内存. 厉害 
    	ucontext_t main;	//上下文信息 
    	int nco;	//实际的co指针个数 
    	int cap;	//co指针数组大小 
    	int running;	// 当前处理的co数组id 或 -1 
    	struct coroutine **co; //co指针数组 
    }; 
    
    // ptrdiff_t 用于表示指针间的"距离",对于指针加减的结果可用这个类型来表示. 
    struct coroutine { 
    	coroutine_func func; //用户自己定义的函数 
    	void *ud;	 //用户自己定义的函数,所传进来的參数,在此为main中的statuc arg 
    	ucontext_t ctx;	 //上下文信息就不用多说了 
    	struct schedule * sch; //指向co所归属的Sch. 
    	ptrdiff_t cap;	 //容量 
    	ptrdiff_t size;	//占用的栈大小 
    	int status;	 // COROUTINE_SUSPEND/COROUTINE_READY 
    	char *stack;	//在yield/resume时发挥保存和恢复作用 
    }; 

    2. 64位指针的传递 

    //注意这里从兼容性角度把S这个指针拆了下,原因是大部份编译器在32/64位下, 
    	//sizeof(指针)返回的长度是不一样的, 32位下是4个字节,64位下是8个字节 
    	//所以在makecontext()的这个可变參数中,将其拆分成了两个32位的指针来传. 
    	//附:在运行地址运算时,多用 uintptr_t 和 uint32_t,更清晰,安全性与兼容性更好 
    	uintptr_t ptr = (uintptr_t)S; 
    	makecontext(&C->ctx, (void (*)(void)) mainfunc, 2, (uint32_t)ptr, (uint32_t)(ptr>>32)); 

    3. 上下文内存和栈内存的一些处理 
    栈拷贝,按需分配 
    _save_stack(struct coroutine *C, char *top) 
    top - &dummy 确有用的好.
    top是栈顶地址, 通过top - &dummy得到栈的实际所需大小分配组C->stack, 
    然后在resume时能够从这弄回去.
    引用: 
    "由于,在我的应用场合,coroutine 切换的那一刻,使用的堆栈并不多(它可能调用一些须要大量堆栈的库函数,但那些库函数中并不会发生切换),所以,在切换的时刻做栈拷贝是能够接受的。coroutine 切换并不算频繁,这个切换成本是可控的。" 



    char stack[STACK_SIZE]; //执行时,co上下文用的就是这块内存
    引用: 
    "其次,我不希望使用 coroutine 的人太考虑 stack 大小的问题。就是说,用户在 coroutine 内能够使用的 C stack 大小和主线程一样多。" 



    4. 在开发32/64位程序时,以后应当多使用ptrdiff_t,uintptr_t 和 uint32_t这类为了跨平台而定义的东东. 
    这类东西定义在 stdint.h 中. 在Windows下我用vs2005尝试时,悲剧的发现2005不支持这个,查到的解决方法是訪问 
    http://www.azillionmonkeys.com/qed/pstdint.h 
    然后将里面的内容拷贝到自己新增的stdint.h中即可用了,以后如vs2010支持了再去掉即可了. 



    协程库这东西不简单。

    MAIL: xcl_168@aliyun.com
    BLOG: http://blog.csdn.net/xcl168

  • 相关阅读:
    VMware Workstation 14 Pro永久激活密钥
    maven属性、profile、资源过滤、不同环境构建项目
    控制返回前台字段
    jsonp 返回以前必须要再转一次json
    doPost方法不支持 a 标签和地址栏直接输入地址访问
    设置响应头控制浏览器的缓存
    获取请求头、设置响应头、设置缓冲区
    重定向与错误发送
    文件下载
    web 应用响应乱码问题
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4208178.html
Copyright © 2011-2022 走看看