zoukankan      html  css  js  c++  java
  • coroutine

    1)lua coroutine使用方法
    http://timyang.net/lua/lua-coroutine/

    co = coroutine.create(function ()
            for i=1,10 do
                print("co", i)
                coroutine.yield()
            end
        end)
    
    从主线程调用
    coroutine.resume(co)
    会依次打印1到10
    View Code

    说明
     LUA提供lua_newthread用于手工创建一个coroutine
     lua_yield用于挂起一个coroutine,不过该函数只能用于coroutine内部
     lua_resume用于启动一个coroutine,它可以用于coroutine没有运行时启动之,也可以用于coroutine挂起时重新启动
    之。lua_resume在两种情况下返回:coroutine挂起或者执行完毕,否则lua_resume不返回
    2)为什么要用coroutine?

        每个coroutine有自己私有的stack及局部变量。
        同一时间只有一个coroutine在执行,无需对全局变量加锁。
        顺序可控,完全由程序控制执行的顺序。而通常的多线程一旦启动,它的运行时序是没法预测的,因此通常会给测试所有的情况带来困难。所以能用coroutine解决的场合应当优先使用coroutine。

        协程最大的应用是取代回调机制,当需要异步执行的时候,启动一个协程,然后当前协程挂起去处理其他事务。异步结果完成后再继续执行,看上去是阻塞但实际上不会影响其他应用,另外一个作用是实现复杂跌代器。

    3) 如何实现coroutine?
    a)云风大师有一个实现 http://blog.codingnow.com/2012/07/c_coroutine.html
    其主要原理是使用c posix函数setcontext来修改context(http://en.wikipedia.org/wiki/Setcontext)
    b) 对应于windows下的函数是SetThreadContext
    codeproject下有一个帖子Unix ucontext_t Operations on Windows Platforms基于windows api实现了setcontext函数
    http://www.codeproject.com/Articles/4225/Unix-ucontext_t-Operations-on-Windows-Platforms
    示例代码

    /* testcontext.c : demo of ucontex_t operations */
    #include <stdio.h>
    #include <stdlib.h>
    #include <ucontext.h>
    
    ucontext_t auc,buc,mainuc;
    
    void a()
    {
        int i;
    
        for (i = 0; i < 10; i++)
        {
            printf("a");
            swapcontext(&auc, &buc);        /* switch to thread B */
        }
    
        printf("\nswitching to main\n");
        swapcontext(&auc, &mainuc);         /* switch to main thread */
    }
    
    void b()
    {
        int i;
    
        for (i = 0; i < 10; i++)
        {
            printf("b");
            swapcontext(&buc, &auc);        /* switch to thread A */
        }
    }
    
    int main(void)
    {
        printf("start\n");                  /* main thread starts */
    
        /* Set up context for thread A (Unix code, see manpages) */
        getcontext(&auc);
        auc.uc_stack.ss_size = 16 * 1024;
    
        if ((auc.uc_stack.ss_sp = malloc(auc.uc_stack.ss_size)) == NULL)
            perror("malloc"), exit(1);
    
        auc.uc_stack.ss_flags = 0;
        makecontext(&auc, a, 0);
    
        /* Set up context for thread B */
        getcontext(&buc);
        buc.uc_stack.ss_size = 16 * 1024;
    
        if ((buc.uc_stack.ss_sp = malloc(buc.uc_stack.ss_size)) == NULL)
            perror("malloc"), exit(1);
    
        buc.uc_stack.ss_flags = 0;
        makecontext(&buc, b, 0);
    
        /* Switch to A */
        getcontext(&mainuc);           /* Save the context of main thread */
        swapcontext(&mainuc, &auc);    /* Switch to thread A */
    
        printf("\ndone\n");  /* Execution control returned to main thread */
        return 0;
    }
    运行结果
    C:\>testcontext.exe
    start
    abababababababababab
    switching to main
    
    done
    C:\>
    View Code

    c)context之类api的实现
    在FreeBSD上你可以参考libc里的makecontext的实现:
    /usr/src/lib/libc/i386/gen/makecontext.c

    4)俺在github上的测试代码

    https://github.com/cutepig123/TestCoroutine/



  • 相关阅读:
    cocos2d-x 3.0rc1 编译cpp-testsproject
    [wxWidgets]_[0基础]_[不常见但有用的类wxStandardPaths]
    教你摆脱低级程序猿 项目中cocopads的安装使用
    Android使用代码模拟HOME键的功能
    UVA 1508
    asp.net mvc5 安装
    Java_并发线程_Semaphore、CountDownLatch、CyclicBarrier、Exchanger
    crm操作产品实体
    BZOJ 3172 [Tjoi2013]单词 AC自己主动机(fail树)
    ADO与ADO.Net
  • 原文地址:https://www.cnblogs.com/cutepig/p/3130113.html
Copyright © 2011-2022 走看看