goroutine阻塞和解除阻塞这两个过程是什么样的
来源:1-6 Go 语法背后的秘密
Garry_27
2021-05-16 14:42:31
曹大当一个goroutine被阻塞是这个G被放在哪里这个过程是什么样的,当解除阻塞过又是什么样的。还有这两个过程都是当前M对应的G0调度的吗
2回答
Xargin
2021-05-16
阻塞分两种:
可接管阻塞:
这部分流程
阻塞走的是 runtime.gopark/runtime.goparkunlock
恢复走的是 runtime.goready/runtime.ready,ready 的调用位置就是各种结构的唤醒流程
比如 channel 的,send 调用的时候,会看看 recvq 上有没有等待的 goroutine,如果有,就调用 goready 唤醒它
比如 mutex 的,unlock 的时候,会把 sema tree 上对应的等待队列的 goroutine 唤醒
ppt 上列的几种情况你都可以按这个思路找一下阻塞进等待结构(一般都是个队列),和唤醒流程
被阻塞的 g 要放在哪里,这个看 ppt 可接管阻塞的那页,有很多种情况,都列出来了。
不可接管阻塞:
这种只能让线程卡在那里,等恢复以后要看这个线程 M 绑定的 P 是不是被 sysmon 拿走了,如果已拿走,需要把这个 G 主动放到队列里
Xargin
2021-05-16
gopark
goready
这两部分不是在 g0 里,runtime 切换到 g0 一般有会调用单独的函数,比如 mcall,systemstack 之类的
相似问题