ucontext.h
void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
int swapcontext(ucontext_t *oucp, ucontext_t *ucp);
在 System-V 环境中,有一个类型叫做 ucontext_t
和四个函数 getcontext()
, setcontext()
, makecontext()
, swapcontext()
,它们定义在
getcontext()
获取当前的 context,setcontext()
设置当前的 context ,也就是激活这个 context
makecontext()
函数修改 ucp
指向的 context(通过 getcontext()
调用获得)。在调用 makecontext()
之前,调用方必须为 context 分配新的栈,并且假定他的地址是 ucp->uc_stack
,定义一个后继 context,假定他的地址是 ucp->uc_link
。当 context 稍后激活调用的函数,传递下面的 int 序列参数,调用这必须制定这些参数的数量,当这个函数返回,接下来的 context 被激活,如果接下来的 context 的指针是 NULL, 线程退出。
swapcontext()
函数保存当前的 context(保存在 oucp 中),然后激活被 ucp 指向的 context。
图一:
Coroutine
Coroutine 就是依赖 ucontext 实现的,给每一个 context 绑定上一个函数,每次激活 Context 就是调用这个函数。每一个 Coroutine 有四个状态,状态图如下:
图二:state
这里还需要解决的一个问题就是栈状态转换的问题。
图二:schedule
为什么这里 Schedule 需要一个 ucontext_t?