协程

在第一次看见这个词后,觉得和进程线程一定有渊源,于是开始查资料,了解它。
看了很多资料,发现很懵逼,知道看见一句话,协程相当于用户级线程。。。就明白是怎么一回事了。
协程有很多库
我们先看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 
#include 
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

你可能感兴趣的:(linux)