协程理论认识
笔记取自:
【协程革命】理论篇 https://www.bilibili.com/video/BV1K14y1v7cw
主旨
协程是可以暂停和恢复的函数。
在一个地方暂停后,又在同样的地方恢复。
为什么需要暂停?一些场景
- 等待资源就绪(网络IO)
- UI渲染时处理业务逻辑
- 游戏技能计算,每一帧计算飞行轨迹然后处理其他逻辑
可以归纳为有其他优先级更高的事件发生时,交处执行权。但这不是线程的切换,协程只是一个函数,协程的切换是函数间的切换(可能切换到另一个线程内的协程)。
暂停与恢复
协程暂停了,然后恢复的是哪个协程?
普遍来说,有一个调度器控制协程切换的整个行为,它负责挑选合适的协程进行运行。
一个协程暂停,它可能返回上层调用它的函数,可能直接返回调度器,也可能切换到另一个协程。
- 回到调度器,协程调用链得到保存
- 回到上层调用,比如说python的yield产生一个数据
- 直接恢复其他协程而不通知调用器,这个最危险(对称式协程)
协程与线程
调度器存放了许多被暂停的协程,多线程争抢协程运行。
实现协程
一个协程要做到再恢复,就必须有个地方存上次离开的信息(上下文信息),根据地方的不同,分为有栈协程和无栈协程。
无栈协程对应一个结构体,这个结构体保存了所有协程必要的信息。有栈协程对应了一个2000字节的内存空间,这2000字节的空间可以当作栈使用。
两者优缺点:
- 有栈申请空间浪费,空间大小不好确定。无栈内存紧凑
- 有栈递归快,无栈慢
协程切换为什么比线程快
在用户级线程中,线程由程序通过线程库实现,线程管理由应用负责,线程切换只需要在用户态完成。
1)协程切换完全在用户空间进行,线程切换涉及特权模式切换,需要在内核空间完成;
2)协程切换相比线程切换做的事情更少。
当前协程的 CPU 寄存器状态,称之为CPU上下文
除了和协程相同基本的 CPU 上下文,还有线程私有的栈和寄存器等,说白了就是上下文比协程多一些。