协程(Coroutine)是什么?

Coroutine不过是一种特殊的subroutines(Subroutines即过程调用)。以协程与函数类比比较,当调用一个函数时,程序从函数的起始地址开始执行,到函数执行结束返回,这就是整个函数的生命周期。函数在它的生命周期中,只可能返回一次。而协程在执行的过程中可以调用其他的协程,保护上下文切换到其他协程,之后协程调用返回恢复到调用的地址继续执行。这个过程类似于多线程的线程的切换。在这个过程中,协程与协程之间是对称的关系(symmetric)。实际上,协程不一定都是这种对称的关系,还存在一种非对称的协程模式(asymmetric coroutines)。非对称协程其实也比较常见,libco其实就是一种非对称协程。

非对称协程(asymmetric coroutines)是跟一个特定的调用者绑定的,协程让出CPU时,只能让回给调用者。何为非对称呢?在于协程的调用(call/resume)和返回(return/yield)的地位不对等。程序控制流转移到被调用者协程,而被调用者只能返回最初调用它的协程。

对称协程(symmetric coroutines)在于协程调用和返回的地位是对等的。启动之后就跟启动之前的协程没有任何关系了。协程的切换操作,一般而言只有一个操作,yield,用于将程序控制流转移给其他的协程。对称协程机制一般需要一个调度器的支持,按一定调度算法去选择yield的目标协程。

Go 语言提供的协程,其实就是典型的对称程。不但对称,goroutines 还可以在多个线程上迁移。这种协程跟操作系统中的线程非常相似,甚至可以叫做“用户级线程”了。而 libco 提供的协程,虽然编程接口跟pthread 有点类似,“类 pthread 的接口”,“如线程库一样轻松”,本质上却是一种非对称协程。这一点不要被表象蒙蔽了。事实上,libco 内部还为保存协程的调用链留了一个 stack 结构,而这个 stack 大小只有固定的 128。使用 libco,如果不断地在一个协程运行过程中去启动另一个协程,随着嵌套深度增加可能会造成这个栈空间溢出。

关于协程的图示:
在这里插入图片描述

协程的理解:

协程的本质与线程一样依然是执行控制流的实体,较之于线程:为了解决线程系统调用的花销,进一步细分出协程。协程调度是由用户态的协程库实现的,操作系统无法直接参与协程的调度。协程具有更轻量级的执行体也就是数据实体,协程的三要素-执行的函数,栈内存,协程控制块,只占较少的资源空间。创建、销毁、上下文切换等效率很高。但是协程也有其一定的缺陷,cpu的执行权限在线程的协程中,如果协程阻塞等那么整个线程都将被阻塞。体现了协程执行控制流的一致性。

参考资料:https://github.com/zhoudayang/libco

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值