【sylar】框架篇-Chapter5-协程模块

本文介绍了sylar C++高性能分布式服务器框架中基于ucontext.h实现的非对称协程库。协程作为一种轻量级线程,能有效提升并发性能。sylar的协程模块利用线程局部变量管理协程上下文,通过swapcontext进行上下文切换。协程与IO多路复用结合,解决了高并发场景下的解决方案。此外,文章强调了协程同步的注意事项,如避免在协程中使用线程级别的锁。

站在巨人的肩膀上

C++高性能分布式服务器框架

从零开始重写sylar C++高性能分布式服务器框架

概述

  • 协程是一种用户态的轻量级线程。
    • 轻量级:相对于线程而言,协程比较轻量。在一个服务器上线程的数量不能太多,也就是上百个线程的级别,否则会产生性能问题。而协程可以轻松达到达到百万级别。
    • 协作式:协程是用户态的概念,对操作系统无感知。操作系统感知不到协程的存在,只能感知到线程和进程的存在。协程的调度是在用户态自己调度。一般协程的调度是协作式的调度。
  • 根据控制传递机制的不同区分出了对称协程和非对称协程。
    • 非对称协程知道它的调用者,其在挂起时转让控制权给它的调用者,然后调用者根据算法调用其他非对称协程进行工作。具体来讲,非对称协程是跟一个特定的调用者绑定的,协程让出 CPU 时,只能让回给原调用者。那到底是什么东西“不对称”呢?其实,非对称在于程序控制流转移到被调协程时使用的是 call/resume 操作,而当被调协程让出 CPU 时使用的却是 return/yield 操作。此外,协程间的地位也不对等,caller 与 callee 关系是确定的,不可更改的,非对称协程只能返回最初调用它的协程。
    • 对称协程都是等价的,控制权直接在对称协程之间进行传递,即对称协程在挂起时主动指明另外一个对称协程来接收控制权。对称协程与非对称协程不一样,启动之后就跟启动之前的协程没有任何关系了。协程的切换操作,一般而言只有一个操作,yield,用于将程序控制流转移给另外的协程。对称协程机制一般需要一个调度器的支持,按一定调度算法去选择 yield 的目标协程。
  • sylar 的协程模块是基于 ucontext.h 实现的非对称协程库。结构体 ucontext_t 保存了程序当前运行的上下文,例如寄存器信息(这些寄存器记录了函数栈帧、代码的执行位置等信息)等。
  • ucontext_t 结构体与具体平台相关,但至少会有以下四个成员:
    ucontext_t *uc_link     	// Pointer to the context that is resumed when this context returns. 
    sigset_t    uc_sigmask  	// The set of signals that are blocked when this context is active. 
    stack_t     uc_stack    	// The stack used by this context. 
    mcontext_t  uc_mcontext  	// A machine-specific representation of the saved context. 
    
  • ucontext.h 还提供了以下四个函数:
    int getcontext(ucontext_t *ucp);
    - 获取当前上下文
    
    int setcontext(const ucontext_t *ucp);
    - 恢复 ucp 指向的上下文,但这个函数不会返回,而是会跳转到 ucp 上下文对应的函数中执行,相当于变相调用了函数。
    
    void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
    - 修改由 getcontext 获取到的上下文指针 ucp,将其与一个函数 func 进行绑定,支持指定 func 运行时的参数。
    - 在调用 makecontext 之前,必须手动给 ucp 分配一段内存空间,存储在 ucp->uc_stack 中,这段内存空间将作为 func 函数运行时的栈空间。
    - 同时也可以指定 ucp->uc_link,表示函数运行结束后恢复 uc_link 指向的上下文。
    - 如果不赋值 uc_link,那 func 函数结束时必须调用 setcontext 或 swapcontext 以重新指定一个有效的上下文,否则程序就跑飞了。
    - makecontext 执行完后,ucp 就与函数 func 绑定了,调用 setcontext 或 swapcontext 激活 ucp 时,func 就会被运行。
    
    int swapcontext(ucontext_t *restrict oucp, const ucontext_t *restrict ucp);
    - 恢复 ucp 指向的上下文,同时将当前的上下文存储到 oucp 中。
    - 和 setcontext 一样,swapcontext 也不会返回,而是会跳转到 ucp 上下文对应的函数中执行,相当于调用了函数。
    - swapcontext 是 sylar 非对称协程实现的关键,线程主协程和子协程用这个接口进行上
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值