在第一次看见这个词后,觉得和进程线程一定有渊源,于是开始查资料,了解它。 看了很多资料,发现很懵逼,知道看见一句话,协程相当于用户级线程。。。就明白是怎么一回事了。 协程有很多库 我们先看ucontext库
其中最主要是四个个函数
int getcontext(ucontext_t *ucp);//获取当前上下文 int setcontext(const ucontext_t *ucp);//回复协程ucp保存的上下文 void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...);//将协程ucp与函数fun绑定 int swapcontext(ucontext_t *restrict oucp, const ucontext_t *restrict ucp);//执行ucp绑定的函数,并把当前上下文保存在oucp中其中ucontext_t相当于进程PCB
接下来看个例子
#include <iostream> #include <ucontext.h> using namespace std; static char g_stack[2048]; static ucontext_t ctx,ctx_main; void func() { cout << "enter func" << endl; swapcontext(&ctx, &ctx_main); cout << "func1 resume from yield" << endl; } int main() { getcontext(&ctx);//将当前上下文保存在ctx中 ctx.uc_stack.ss_sp = g_stack;//协程使用的栈,这里的栈不同于进程线程的栈,只能说模拟了进程线程的栈的功能,实际就是自己分配的一块内存区,这个内存区用来实现栈的功能 ctx.uc_stack.ss_size = sizeof(g_stack); ctx.uc_link = &ctx_main;//ctx.uc_link指向下一个协程“pcb”如果ctx协程运行结束,会自动调用ctx_main协程 makecontext(&ctx, func, 0);//将func()函数与ctx绑定,如果不绑定,运行协程后ctx默认从ctx保存的上下文处执行 cout << "in main, before coroutine starts" << endl; swapcontext(&ctx_main, &ctx);//保存当前上下文到ctx_main,并执行ctx绑定的函数 cout << "back to main" << endl; swapcontext(&ctx_main, &ctx); cout << "back to main again" << endl; return 0; }运行结果
in main, before coroutine starts enter func back to main func1 resume from yield back to main again