zoukankan      html  css  js  c++  java
  • 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
    ");
    }
    
    int main()
    {
        printf("in main
    ");
        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
    ");
        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

  • 相关阅读:
    3、Semantic-UI之定义容器
    2、Semantic-UI之网格布局
    1、Semantic-UI之开发环境搭建
    PyCharm创建普通项目配置支持jinja2语法
    CentOS 7安装GitLab、汉化、配置邮件发送
    Docker swarm 实战-部署wordpress
    线程和进程
    NGINX内置变量
    iTerm2 + Oh My Zsh 打造舒适终端体验
    CentOS 7修改网卡名称
  • 原文地址:https://www.cnblogs.com/xcantaloupe/p/11102369.html
Copyright © 2011-2022 走看看