Go 的 goroutine 调度基于用户态 GMP 模型采用协作与抢占混合机制不依赖 OS 线程轮转其执行需调度点触发如函数调用、系统调用返回、Gosched 或抢占纯 CPU 循环无调度点将导致 goroutine 卡住。Go 的 goroutine 调度不是靠操作系统线程轮转而是 GMP 模型在用户态做的协作抢占混合调度 —— 你写的 go f() 不会立刻执行也不保证马上被 CPU 执行更不等于一个 OS 线程。goroutine 为什么有时不立即运行因为 runtime.schedule() 只在特定时机触发比如当前 goroutine 主动让出runtime.Gosched()、系统调用返回、函数调用栈增长检查点、或被抢占如超过 10ms 的连续运行。它不依赖时间片中断也没有“就绪队列优先级”这种概念。常见错误现象for {} 死循环里起的 goroutine 一直卡住select {} 后没反应主 goroutine 退出后子 goroutine 没机会跑。确保有调度点避免纯计算无函数调用的长循环可插入 runtime.Gosched() 或小 sleep主 goroutine 别直接退出用 sync.WaitGroup 或 time.Sleep() 等待否则整个程序退出所有 goroutine 被强制终止阻塞系统调用如文件读写、网络收发会自动让出 P但纯 CPU 计算不会 —— 这是新手最常忽略的调度盲区GMP 中的 P 被谁绑定什么时候解绑PProcessor是调度关键资源每个 P 维护本地可运行队列。它默认最多与 MOS 线程一对一绑定但仅当 M 处于执行状态且未被阻塞时才持有 P一旦 M 进入系统调用或睡眠P 就会被剥离交给其他空闲 M 抢占。立即学习“go语言免费学习笔记深入” RedClaw 百度推出的手机端万能AI Agent助手