用户态线程,或者称之为协程,因为具有更好的扩展性,在现在的服务端编程中越来越受到重视。今天的文章会介绍在 linux 系统下,如何使用 ucontext 来实现协程库。
用户态实现线程库其实有两个常见的选择,其一是 setjmp,但是因为其要想做到协程之间的栈隔离,需要使用汇编语言,实在非大多数程序员所长,这里就不展开介绍了。
另一个方案就是本文的主角 ucontext。来看一下今天的主角:
#include <ucontext.h>
int
getcontext(ucontext_t *ucp);
int
setcontext(const ucontext_t *ucp);
void
makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
int
swapcontext(ucontext_t *oucp, const ucontext_t *ucp);
getcontext 会将当前执行上下文保存在 ucp 中(执行上下文包括但不局限于一些重要的寄存器),而这个上下文对象之后可以进行 resume (恢复)。
makecontext 第一个参数必须是经过 getcontext 初始化过的上下文对象,而且必须要注意的是,在调用前必须给上下文分配单独的栈空间,用于执行 func 函数。这样一来也就达到了栈空间隔离的效果,具体代码见后续 demo
setcontext 接受的参数必须是一个经过 getcontext 初始化或者 makecontext 修改过的上下文对象。setcontext 函数不会返回到调用者,而是会恢复之前的上下文的执行。如果 ucp 是 getcont