c++ uconcontext.h实现协程

Posted xcantaloupe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

代码地址

https://github.com/linzhongli/coroutine

以上是关于c++ uconcontext.h实现协程的主要内容,如果未能解决你的问题,请参考以下文章

微信终端自研 C++协程框架的设计与实现

Kotlin协程源码分析-7 Context左向链表

基于libco的c++协程实现(时间轮定时器)

从无栈协程到 C++异步框架

C++学习记录:一个协程库的源码分析

C++学习记录:一个协程库的源码分析