You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于OS调度器与Go调度器上下文切换的两类技术问询

关于线程调度与Go协程调度的疑问解答

问题1:OS调度器能否在映射到内核级线程的用户级线程之间执行上下文切换?

这个问题要结合用户级线程(ULT)和内核级线程(KLT)的映射模型来看:

  • 一对一模型:每个用户级线程对应一个独立的内核级线程。此时OS调度器只能感知到内核级线程,它的上下文切换操作针对的是内核级线程,本质上是间接完成了用户级线程的切换,但OS并不会直接识别或操作用户级线程本身。
  • 多对一模型:多个用户级线程绑定到同一个内核级线程。OS完全看不到用户级线程,只能调度这个唯一的内核级线程;用户级线程之间的上下文切换完全由用户态的线程调度器负责,OS无法介入。
  • 多对多模型:多个用户级线程映射到一组内核级线程。OS依然只负责内核级线程的调度,用户级线程到内核级线程的映射、以及用户级线程之间的切换,由用户态调度器控制,OS不会直接在用户级线程之间执行切换。

简单来说:OS调度器无法直接在用户级线程之间执行上下文切换,它的调度对象始终是内核级线程;用户级线程的切换要么由用户态调度器完成,要么通过OS切换内核级线程间接实现。

问题2:当goroutine发起系统阻塞调用时,谁会率先执行上下文切换:OS还是Go调度器?

Go采用的是M:N调度模型(M=内核线程,G=goroutine,P=逻辑处理器),当goroutine A发起系统阻塞调用时,Go调度器会率先执行上下文切换操作:

  1. 当Go调度器检测到goroutine A即将进入系统调用阻塞时,会立即将绑定的逻辑处理器P与当前内核线程M解绑;
  2. 随后把这个空闲的P分配给其他处于空闲状态的内核线程M',让M'可以调度其他等待执行的goroutine;
  3. 当系统调用真正导致内核线程M阻塞后,OS调度器才会介入,将M从CPU上切换出去,调度其他就绪的内核线程运行。

也就是说,Go调度器会先完成goroutine调度层面的上下文切换(P的转移),避免CPU资源浪费,之后OS才会因为内核线程阻塞执行内核层面的切换。


内容的提问来源于stack exchange,提问作者Tarun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:35:10