FQA
- 协程解决了什么问题。
- 协程在什么场景下使用。
- 协程切换原理
abstract
- 并发不是并行(拆分独立的任务)
- 协程切换,本质是函数运行时上下文切换
- 协程函数上下文:寄存器数据 内存数据。
concrete
并发是两个队列交替使用一台咖啡机,并行是两个队列同时使用两台咖啡机
协程 的发明主要是为了解决 Concurrency(并发) 问题,
而 线程 的发明主要解决的 Parallelism(并行) 问题。
并发是是一个设计架构,协程用同步思想代替异步实现。
画重点
- 理解协程切换原理,首先需要理解函数的运行原理。(《x86-64 下函数调用及栈帧原理》)
- 协程是啥?它本质上就是一个函数体,与普通函数相比,它只是特殊一点而已。
- 协程函数上下文:寄存器数据 内存数据。
- 协程切换(yield/resume)本质是函数运行时上下文切换。
- 系统默认为函数运行时分配堆栈内存,而 libco 为协程函数分配堆空间(独立栈/共享栈)使其工作。
- libco 切换核心源码在
co_routine.cpp/co_swap()/coctx_swap()
,coctx_swap
通过汇编实现。 - 汇编源码的理解,关键对
call/ret
这两个汇编指令理解:call 调用函数,ret 返回函数运行地址;当执行这两个指令时寄存器和程序是如何在内存上压栈出栈的。 - 用 lldb / gdb 走一下
coctx_swap
这段汇编源码逻辑,观察寄存器与内存数据的变化。
遗留问题:
普通函数递归相互调用 出现栈异常现象 【一直增加新的栈空间】
协程为什么不会出现,他也不是反复调用的吗?【在已经的栈上jump跳转】
协程切换却能将当前运行的函数,切换到另外一个函数运行,这是协程的神奇之处。
参考:
https://wenfh2020.com/2020/12/17/libco-switch/