go concurrency
2012 年 11 月 6 日
当一个G系统阻塞了, 比如(调用了sleep或者I/O系统调用), G处于_Gsyscall状态,M也处于 block on syscall 状态,此时的M可被抢占调度,
由于线程不能同时执行代码和被阻塞在syscall上,所以我们需要传递上下文,以便它能够继续调度
go runtime却不会让对应的P(context)被阻塞(想一下,P的local runqueue下此时可能还挂了一串而goroutine呢) 而是去线程缓存池(M cached pool)中Get一个M出来如下图M1,把自己挂上去,从local runqueue上pop一个G出来继续执行;如果没有其它idle的M,但P的Local队列中仍然有G需要执行,则创建一个新的线程,并将P与之绑定,顺序执行P中下一个G.

syscall.jpg