协程

#include <ucontext.h>
#include <iostream>
using namespace std;
static ucontext_t ctx[3];

static void func_1(void) {
  int a;
  // 执行点2,协程1在这里yield,pthread线程恢复执行协程2的任务函数,即令协程2 resume。
  cout << "bbb" << endl;
  swapcontext(&ctx[1], &ctx[2]);
  cout << "ddd" << endl;
  // 执行点4,协程1从这里resume恢复执行。
  // func_1 return后,由于ctx[1].uc_link = &ctx[0],将令main函数resume。
}

static void func_2(void) {
  int b;
  // 协程2在这里yield,pthread线程去执行协程1的任务函数func_1。
  cout << "aaa" << endl;
  swapcontext(&ctx[2], &ctx[1]);
  cout << "ccc" << endl;
  // 执行点3,协程2从这里resume恢复执行。
  // func_2 return后,由于ctx[2].uc_link = &ctx[1],将令协程1 resume。
}

int main(int argc, char **argv) {
  // 定义协程1和协程2的私有栈。
  // 在这个程序中,协程1和协程2都在main函数return之前执行完成,
  // 所以将协程私有栈内存区定义为main函数的局部变量是安全的。
  char stack_1[8096] = { 0 };
  char stack_2[8096] = { 0 };

  // 初始化协程1的ucontext_t结构ctx[1]。
  getcontext(&ctx[1]);
  // 在ctx[1]结构中指定协程1的私有栈stack_1。
  ctx[1].uc_stack.ss_sp   = stack_1;
  ctx[1].uc_stack.ss_size = sizeof(stack_1);
  // ctx[0]用于存储执行main函数所在线程的cpu的各个寄存器的值,
  // 下面语句的作用是,当协程1的任务函数return后,将ctx[0]中存储的各寄存器的值加载到cpu的寄存器中,
  // 也就是pthread线程从main函数之前的yield调用的返回处继续执行。
  ctx[1].uc_link = &ctx[0];
  // 指定协程1的任务函数为func_1。
  makecontext(&ctx[1], func_1, 0);

  // 初始化协程2的ucontext_t结构ctx[2]。
  getcontext(&ctx[2]);
  // 在ctx[2]结构中指定协程2的私有栈stack_2。
  ctx[2].uc_stack.ss_sp   = stack_2;
  ctx[2].uc_stack.ss_size = sizeof(stack_2);
  // 协程2的任务函数return后,pthread线程将从协程1的yield调用的返回点处继续执行。
  ctx[2].uc_link = &ctx[1];
  // 指定协程2的任务函数为func_2。
  makecontext(&ctx[2], func_2, 0);

  // 执行点1,将cpu当前各寄存器的值存入ctx[0],将ctx[2]中存储的寄存器值加载到cpu寄存器中,
  // 也就是main函数在这里yield,开始执行协程2的任务函数func_2。
  swapcontext(&ctx[0], &ctx[2]);
  cout << "eee" << endl;
  // 执行点5,main函数从这里resume恢复执行。
  return 0;
}

 

上一篇:idea gradle lombok找不到符号


下一篇:Spring源码阅读环境搭建