go GMP调度模型
goroutine
go协程的本质是用户态的线程,相比于传统的内核态线程,在性能方面有更多优点
- 协程的切换发生在用户态,不用切换到内核态,不用处理时钟中断,效率更高。
- 协程栈空间更小(go支持协程栈的自动增长),一般在4KB左右。而线程栈一般在4MB左右。从而可以创建大量协程。
但是从程序员的角度来看,协程和线程用起来体验差不多。
GMP调度模型
- G(goroutine):协程。
- M(machine):实际跑任务的机器,对应一个线程。
- P(processor):调度器,里面保存了运行队列,抽象地看相当于是一个处理器。
一个P绑定到一个M上,每个P都会维护一个本地的G队列,这样每次从队列中取出G时不用竞争。如果本地队列空了,那么就会去全局G队列取一些过来。
每当进行磁盘IO,网络IO,协程休眠时协程就会让出,被调度。
抢占式调度
- 栈增长时调度:在go1.14之前就实现了,如果一个协程长时间占据CPU,那么在调用函数的时候执行编译器插入的
runtime.morestack
栈增长函数,里面会判断是否进行抢占式调度。 - 基于信号的抢占式调度:go1.14新特性,对于恶意的抢占程序,比如死循环,上面的方式也无法抢占。于是基于操作系统信号机制,当协程长时间占据CPU,那么给对应的线程发送
sigurg
信号,在注册的信号处理函数里面实现协程的切换。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)