ucontext.h

  1. void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
  2. int swapcontext(ucontext_t *oucp, ucontext_t *ucp);

在 System-V 环境中,有一个类型叫做 ucontext_t 和四个函数 getcontext(), setcontext(), makecontext(), swapcontext() ,它们定义在 中,允许一个进程中多线程的用户级别的 context 改变。

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-ucontext.png
图一:

Coroutine

Coroutine 就是依赖 ucontext 实现的,给每一个 context 绑定上一个函数,每次激活 Context 就是调用这个函数。每一个 Coroutine 有四个状态,状态图如下:

coroutine-state.png
图二:state

这里还需要解决的一个问题就是栈状态转换的问题。

coroutine-Page-1.png
图二:schedule

为什么这里 Schedule 需要一个 ucontext_t?