c++ uconcontext.h实现协程
c++ uconcontext.h实现协程
什么是协程?
协程是一种程序组件,是由子例程(过程、函数、例程、方法、子程序)的概念泛化而来的,子例程只有一个入口点且只返回一次,而协程允许多个入口点,可以在指定位置挂起和恢复执行。
协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。
一个线程可以拥有多个协程,但是一个时刻只能有协程在执行,协程的调度是非强占式的,只有协程自己主动让出执行权才切换。而非像线程一样是由操作系统调度。
实现协程的重点就是保存当前上下文,切换到要执行的上下文,结束后再返回到保存的上下文
ucontext.h库
ucontext.h库中定义了一个ucontext_t结构体
typedef struct ucontext_t
{
unsigned long int __ctx(uc_flags);
struct ucontext_t *uc_link; //后继上下文
stack_t uc_stack; //该上下文中使用的栈
mcontext_t uc_mcontext;
sigset_t uc_sigmask;
struct _libc_fpstate __fpregs_mem;
} ucontext_t;
这个结构体是用来保存上下文的
并且定义了4个函数用于操作结构体
int getcontext(ucontext_t * ucp);
获取当前上下文, 初始化ucp结构体, 将当前上下文保存到ucp中
void makecontext(ucontext_t *ucp, void(*func)(), int argc, ...);
创建一个上下文
int setcontext(const ucontext_t *ucp);
设置当前的上下文为ucp
int swapcontext(ucontext_t *oucp, ucontext_t *ucp);
保存当前上下文至oucp, 激活ucp上下文
库的使用示例
#include<stdio.h>
#include<ucontext.h>
void funtion(){
printf("run this\n");
}
int main()
{
printf("in main\n");
char stack[1024];
ucontext_t main,other;
getcontext(&main); //获取当前上下文
main.uc_stack.ss_sp = stack; //指定栈空间
main.uc_stack.ss_size = sizeof(stack);//指定栈空间大小
main.uc_stack.ss_flags = 0;
main.uc_link = &other; //将后继上下文指向other
makecontext(&main,funtion,0); //为main指定要执行的函数
swapcontext(&other,&main); //激活main,并将当前上下文保存到other
printf("in main\n");
return 0;
}
output
in main
run this
in main
核心代码
ucontext_t main,other;
getcontext(&main); //获取当前上下文
main.uc_stack.ss_sp = stack; //指定栈空间
main.uc_stack.ss_size = sizeof(stack);//指定栈空间大小
main.uc_stack.ss_flags = 0;
main.uc_link = &other; //将后继上下文指向other
makecontext(&main,funtion,0); //为main指定要执行的函数
swapcontext(&other,&main); //激活main,并将当前上下文保存到other