美文网首页
POSIX的协程/纤程库

POSIX的协程/纤程库

作者: 蟹蟹宁 | 来源:发表于2021-06-23 14:49 被阅读0次

    为支持纤程,POSIX的<ucontext.h>头文件中定义了4个操作函数以及一个结构体,以允许在用户级实现在进程中切换线程的上下文,更加确切的说法应该是,实现多对一的用户线程和内核线程。
    一个结构体:ucontext_t
    4个操作:get/set/make/swap context

    结构体:ucontext_t

    ucontext_t至少包括一下字段:

    typedef struct ucontext_t{
            struct ucontext_t* uc_link;
            sigset_t          uc_sigmask;
            stack_t           uc_stack;
            mcontext_t     uc_mcontect;    
            ...
    }
    

    mcontext是依赖于不同的硬件机器,且不透明。
    uc_ink指向了当前上下文终止时将恢复的上下文(若此上下文是由makecontext创建的),uc_sugmask是该上下文信号集的阻塞信号集,uc_stack是context堆栈;uc_mcontext则用于记录机器寄存器的信息。

    函数体

    int getcontext(ucontext_t*ucp);
    int setcontext(const ucontext_t*ucp);
    

    getcontex()函数将ucp指向的结构体系初始为当前活动的context,而setcontext()则是将当前上下文恢复为ucp所指的上下文,成功调用setcontext()后将不会返回。

    getcontest (&UC);
    printf (“hello”);
    setcontext (&ucp);
    

    此过程是一个死循环且整个过程没有进行堆栈的切换

    如果context是通过getcontext获得,那么协程将从getcontext()的返回点继续执行,就像刚从函数返回。
    如果context是通过makecontext()产生,协程将从其第2位参数func开始执行,当func执行结束时将执行ucp的第1个参数指定的协程,直到uc_link位NULL,线程结束。
    从描述上可以知道makecontext()新创建了堆栈,并在堆栈中压入了uc_link的地址,或一个go_exit类似的处理函数,从而实现上述过程,而getcontext()继承了原堆栈

    void makecontext(ucontext*ucp,void(*func)(),int argc,...)
    int swapcontext(ucontext*oucp,ucontext*ucp)
    

    makecontext()用于修改ucp的值,ucp是通过getcontext()获取的。(直接调用makecontext()会报错)在调用此函数之前需要指定uc_stack和uc_link。
    当此context被activated之后,将会调用func执行,并传递一系列整型参数,由arge指定参数的个数。
    swapcontext会保存当留状态到oucp,并切换到新的ucp中。

    相关文章

      网友评论

          本文标题:POSIX的协程/纤程库

          本文链接:https://www.haomeiwen.com/subject/qeypyltx.html