协程库的实现方式
目前有如下几种方式来实现协程库:
第一种:利用glibc的ucontext函数族。比如
云风的
协程库;
第二种:利用汇编语言来切换运行时上下文。比如
微信的libco;
第三种:利用C语言语法switch-case来实现切换上下文。比如Protothreads;
第四种:利用C语言的setjmp和longjmp。
我们知道一个程序可以包含多个进程,每个进程中可以创建多个线程,在线程中又可以创建成千上万的协程。进程和线程的调度是在内核空间,而协程的创建和调度都在用户空间,这就注定创建和维持协程运行所牺牲的性能,要远比进程和线程小很多很多。协程
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, ucontext_t *ucp);
这4个函数都用到了ucontext_t结构体,它大致的结构为:
typedef struct ucontext {
struct ucontext *uc_link;
sigset_t uc_sigmask;
stack_t uc_stack;
mcontext_t uc_mcontext;
...
} ucontext_t;
其中:
uc_link :当前上下文运行结束时,系统恢复到uc_link指向的上下文;如果该值为NULL,则线程退出;
uc_stack :当前上下文中使用的栈;
uc_sigmask :当前上下文中的阻塞信号集;
uc_mcontext:保存的上下文的特定机器表示,包括调用线程的特定寄存器等;
协程的状态切换:
参考
1.
https://blog.csdn.net/qq910894904/article/details/41911175
2.