前言
讲协程之前,先看一下没有协程的时候我们是怎么运用多线程的
进程/线程的数量越多,切换的成本就越大,也就越浪费
CPU在100%时,60%是在执行程序,40%在切换
什么是协程
-
为什么协程可以大量创建?
进程占用内存 ---> 虚拟内存4GB(32bit OS)
线程占用内存 ---> 约4MB
协程占用内存 ---> 几KB
-
一张图就能理解是协程
-
再用一张图理解协程调度器和协程及线程之间的关系
线程是由CPU调度器调度的,协程同样也有协程调度器进行调度
所以为什么说协程比线程效率高?因为协程的切换不涉及用户态和内核台的切换,在用户态即可完成切换
早期GoLang调度器设计
需要通过加锁解锁来控制协程任务的执行
当这个M1要执行G的时候,这个G任务同时还要执行一个G0,但是因为M1在处理G,导致M1无法处理G0,要将G0交给其他M来处理,简单来说就是无法让同一个线程执行一个协程所衍生出的另一个协程
协程调度器设计
processor处理器相当于操作系统的调度器
Work Stealing机制
此时M2线程对应的P的本地队列中没有协程,会从其他队列中把在排队中的协程拿过来执行
hand off机制
G1协程执行的时候阻塞了,导致G2没办法执行,此时会重新创建 / 唤醒一个Thread线程,将M3和P进行绑定,让M1线程和G1绑定,待G1任务完成后销毁或者等待唤醒