C++协程基础

参考资料

一、什么是协程

1.1 基础知识

通用的说法是协程是⼀种“轻量级线程”,用户态线程”。

  • 可以减少用户态与内核态的切换,相当于一个花里胡哨的函数。

协程的本质就是函数和函数运行状态的组合 。

  • 函数一旦被调用,则只能从头运行到结束
  • 协程可以执行到一半退出(yield),暂时让出CPU执行权;在后面适当时机可以重新恢复运行(resume)。这期间CPU可以运行其他协程。

协程能够半路yield、再重新resume的关键是协程存储了函数在yield时间点的执⾏状态,这个状态称为协程上下文

  • 通过记录当前执行状态下CPU全部寄存器的值来实现
  • 要resume时再把这些值重新设置给CPU

与线程的区别:

  • 线程创建之后,线程的运⾏和调度也是由操作系统⾃动完成的
  • 协程创建后,协程的运⾏和调度都要由应用程序来完成,就和调用函数⼀样,所以协程也被称为“用户态线程”。

1.2 优缺点

优点:

  • 提高资源利用率,提高程序并发性能。协程允许开发者编写异步代码,实现非阻塞的并发操作,通过在适当的时候挂起和恢复协程,可以有效地管理多个任务的执行,提高程序的并发性能。与线程相比,协程是轻量级的,它们的创建和上下文切换开销较小,可以同时执行大量的协程,而不会导致系统负载过重,可以在单线程下实现异步,使程序不存在阻塞阶段,充分利用cpu资源。
  • 简化异步编程逻辑。使用协程可以简化并发编程的复杂性,通过使用适当的协程库或语言特性,可以避免显式的线程同步、锁和互斥量等并发编程的常见问题,用同步的思想就可以编写成异步的程序。

缺点:

  • 无法利用多核资源。线程才是系统调度的基本单位,单线程下的多协程本质上还是串行执行的,只能用到单核计算资源,所以协程往往要与多线程、多进程一起使用。

二、协程的分类

2.1 对称协程与非对称协程

  • 对称协程,协程可以不受限制地将控制权交给任何其他协程。任何⼀个协程都是相互独⽴且平等的,调度权可以在任意协程之间转移。
  • ⾮对称协程,是指协程之间存在类似堆栈的调⽤⽅-被调⽤⽅关系。协程出让调度权的⽬标只能是它的调⽤者。

对称协程更灵活,⾮对称协程实现更简单。

2.2 有栈协程与无栈协程

浅谈有栈协程与无栈协程
有栈协程:用独立的执行栈来保存协程的上下文信息。

  • 当协程被挂起时,栈协程会保存当前执行状态(例如函数调用栈、局部变量等),并将控制权交还给调度器。
  • 当协程被恢复时,栈协程会将之前保存的执行状态恢复,从上次挂起的地方继续执行。

无栈协程:它不需要独立的执行栈来保存协程的上下文信息,协程的上下文都放到公共内存中,

  • 当协程被挂起时,无栈协程会将协程的状态保存在堆上的数据结构中,并将控制权交还给调度器
  • 当协程被恢复时,无栈协程会将之前保存的状态从堆中取出,并从上次挂起的地方继续执行。
  • 协程切换时,使用状态机来切换,就不用切换对应的上下文了,因为都在堆里。

2.3 独立栈与共享栈

独立栈和共享栈都是有栈协程。

共享栈本质就是所有的协程在运行的时候都使用同一个栈空间,每次协程切换时要把自身用的共享栈空间拷贝。

  • 好处是使用公共资源,公共资源内存空间比较大,相对安全,节省内存空间,
  • 坏处是协程频切换需要进行内存拷贝,废CPU

独立栈,也就是每个协程的栈空间都是独立的,固定大小。

  • 好处是协程切换的时候,内存不用拷贝来拷贝去,相对简单
  • 坏处则是内存空间浪费,容易栈溢出。

三、C++的协程

参考资料2。

在 C++ 当中,区别一个函数是不是协程,是通过它的返回值类型来判断的。一个函数的返回值类型如果是符合协程的规则的类型,那么这个函数就是一个协程。

C++ 协程会在开始执行时的第一步就使用 operator new 来开辟一块内存来存放这些信息,这块内存或者说这个对象又被称为协程的状态(coroutine state)。

关键字co_await ,使当前函数(协程)的执行被挂起。其操作对象为等待体(awaiter)。

等待体一般需要实现三个函数,用于挂起和恢复时使用。

  • await_ready:协程挂起
  • await_suspend:用于保存局部变量和挂起点,最为核心的函数之一了
  • await_resume:挂起恢复

四、实现一个简单的协程库

ucontext-人人都可以实现的简单协程库

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值