Go调度器如何处理goroutine阻塞的情况??

  • 前置知识点: go程序中,任何对系统 API 的调用,都会被 runtime 层拦截来方便调度。

  • go一共有4种阻塞的情况,并且这些阻塞都是可以被runtime检测到的,runtime检测到阻塞时就可以进行优化处理。

  1. blocking syscall (for example opening a file) // 系统调用
  2. network input // 网络IO
  3. channel operations
  4. primitives in the sync package // 锁

    4种阻塞可以分为两类:

    分类1 (对应情况2,3,4): (只G阻塞,M,P可用的,要利用起来)

    1.1 用户代码层面的阻塞(channel,锁), 此时M可以换上其他G继续执行。

    1.2 网络阻塞 (netpoller实现G网络阻塞不会导致M被阻塞,仅阻塞G)。

    分类2 (对应情况1): (G,M都被阻塞,P可用,要利用起来)

    2.1 系统调用(open file)

这里的Go调度时机和同步异步系统调用也提供了一种理解。

https://www.cnblogs.com/qcrao-2018/p/11442998.html

  • 请教博客作者后,总结如下

    系统调用分同步异步,对应两种处理方法。一种切换G,一种切换M,但是P不会闲着的(不养闲人)。