1 协程介绍
协程是一种轻量级的线。协程在程序运行时由程序员显式控制调度的,可以在同一个线程中实现多个协程之间的切换,从而实现并发执行的效果。比较经典的理解是:“用同步的方法,做着异步的事情”。
协程避免了线程切换所带来的开销,在一些性能要求高、资源限制多的场合就特别的适用。
协程上下文ucontext_t,里面包含了程序计数器、栈指针、寄存器等信息,它们表示了一个协程的运行状态。通过ucontext_t的简单封装,即可验证 “保存和恢复上下文” 来实现协程的切换的过程。这些其实也是可以用汇编语言来实现的,但是不同的架构的CPU,都要用汇编各自实现一个版本。
2 用ucontext库创建简单的协程
linux上运行,简单的示例:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#define STACK_SIZE 10240
ucontext_t main_context, sub_context;
int count = 0;
void func1(){
while(count ++ < 10){
printf("func1 start \n");
swapcontext(&sub_context, &main_context);
printf("func1 end \n");
}
}
void func2(){
while(count ++ < 10) {
printf("func2 start \n");
swapcontext(&main_context, &sub_context);
printf("func2 end \n");
}
}
int main(int argc, char *argv[]) {
char *stack = (char *)malloc(STACK_SIZE);
getcontext(&sub_context);
sub_context.uc_stack.ss_sp = stack;
sub_context.uc_stack.ss_size = STACK_SIZE;
sub_context.uc_link = &main_context;
makecontext(&sub_context, func1, 0);
func2();
free(stack);
return 0;
}
swapcontext 起到在两个函数中来回切换的作用,这
2.1 分析
2.2 实际输出
func2 start => 对应2.1 中的 1
func1 start => 对应2.1 中的 2
func2 end => 对应2.1 中的 3
func2 start => 对应2.1 中的 4 fun2执行 while循环,到达 func2 start
func1 end => 对应2.1 中的 5
func1 start => fun1执行 while循环,到达 func1 start
func2 end 。。。
func2 start
func1 end
func1 start
func2 end
func2 start
func1 end
func1 start
func2 end
func2 start
func1 end
func1 start
func2 end
PS: 这里只是简单的了解一下协程的概念,期待自己进一步深入学习,实现对网络IO收发的协程封装。
文章参考与<零声教育>的C/C++linux服务期高级架构系统教程学习:链接