面试题:谈谈你对 Golang 调度模型的理解?
在 2020.2.22 这一天,面试了 B 站后台开发的岗位,被问到了这样的一个面试题。一下子就蒙了,今天恶补了一下,整理一下思路,避免下次还蒙。
- 说一下 GMP 模型、global queue、P 的 local queue。
2. Work Stealing,即当一个 P 的 local queue empty 了,为了不同的 P 直接的负载均衡所采取的的策略。什么时候进出 global queue?为什么需要 local queue?[避免了获取 goroutine 产生的锁]。 参考这个:
https://medium.com/a-journey-with-go/go-work-stealing-in-go-scheduler-d439231be64dmedium.com https://medium.com/a-journey-with-go/go-g0-special-goroutine-8c778c6704d8medium.com3. 阻塞调用了,怎么办? 异步的网络调用,通过 netpoller (封装了 os 提供的 I/O 多路复用)来调度,避免产生过多的 M;同步的系统调用,则脱离 P ,将 P 绑定到空闲的 M 或者新建一个 M ,来调度;参照:
The Go netpollermorsmachine.dk https://medium.com/a-journey-with-go/go-concurrency-scheduler-affinity-3b678f490488medium.com https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part2.htmlwww.ardanlabs.com4. 抢占式调度:
当某个goroutine执行超过10ms,sysmon会向其发起抢占调度请求,由于Go调度不像OS调度那样有时间片的概念,因此实际抢占机制要弱很多: Go中的抢占实际上是为G设置抢占标记(g.stackguard0),当G调用某函数时(更确切说,在通过newstack分配函数栈时),被编译器安插的指令会检查这个标记,并且将当前G以runtime.Goched的方式暂停,并加入到全局队列。
https://medium.com/a-journey-with-go/go-goroutine-and-preemption-d6bc2aa2f4b7medium.comReference:
Go 调度模型wudaijun.com![81106203de2d45e06198139325a97a1e.png](https://i-blog.csdnimg.cn/blog_migrate/64b04a2398d1009f12dba12dd9432804.png)