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)

TODO 这2个说法似乎有的矛盾

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

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

  • 请教博客作者后,总结如下
    系统调用分同步异步,对应两种处理方法。一种切换G,一种切换M,但是P不会闲着的(不养闲人)。
posted @ 2020-03-05 19:28  sicnu-yudidi  阅读(2072)  评论(0编辑  收藏  举报