GO调度器模型
GO的调度器可以充分利用多核心CPU,任何时候都有M个go协程在N个系统线程上进行调度,这些线程在最多 GOMAXPROCS 个CPU核心上运行,这种调度模型称之为GMP模型:
- G : 协程(goroutine)
- M : 系统线程(machine)
- P : 处理器(processor)
文章插图
【Golang调度器】每轮调度只需要找一个可运行的G执行它就行,这个查找过程如下:
runtime.schedule() {// 1/61 的概率去全局队列找一个G来运行// 如果没有找到,到本地队列中找// 如果没有找到,//尝试从其他的P中偷取G来运行//如果没有,检查全局队列//如果没有,检查 Net Poller}
GO协程的状态GO协程和线程一样有三种状态,一个协程可以处于下面三种状态中的一种: Waiting ,Runnable 和 Executing。- Waiting : 这种状态意味着协程被暂停运行需要等待某些事情完成才能继续运行 。比如等待一个系统调用的返回或者一个同步调用(原子或者锁操作) 。这种类型的延时是性能低下的主要原因 。
- Runnable : 这种状态说明协程正在等待被运行 。如果有很多协程都在等待运行,那么协程需要等待一段更长的时间,而且每个协程被分配的运行时间也会减少 。这种调度延时也是一种性能低下的原因 。
- Executing : 这种状态说明此协程被放在了M中正在执行它的指令 。
- 使用 go 关键字的地方,go 关键字用于创建协程 。在一个新的协程被创建的时候,就会给调度器一个机会执行调度任务 。
- 垃圾回收,GC是在自己的一套协程中运行,所以在GC过程中需要被调度执行,在GC过程中调度器会优先调度需要接触堆内存的协程
- 系统调用,在系统调用时会导致协程阻塞这个M,调度器会将此协程调度出去或者使用一个新的M来执行队列中的其他协程 。
- 同步和编排,atomic,mutex和channel操作都可能会阻塞这个协程,此时调度器可以调度一个新的协程来运行 。
在图1中,Goroutine-1正在M上运行,此时本地队列中有3个G在等待运行,网络轮询器上是空的 。
文章插图
图2中,Goroutine-1希望进行网络系统调用,此时将Goroutine-1移至网络轮询器上处理异步网络系统调用然后将Goroutine-2调度到M上继续运行 。
文章插图
图3中,网络调用完成,此时Goroutine-1被放回本地队列中,当调度到Goroutine-1时,它可以继续执行接下来的指令,这里最大的好处是执行网络系统调用不需要额外的M,网络轮询器实际是一个系统线程专门用于处理异步网络请求 。
文章插图
同步调用当G调用同步系统调用时会怎样?例如文件相关的系统调用以及使用CGO时调用C函数也是同步调用,此时M会被此G阻塞 。
图4中,Goroutine-1正在M1上运行,他要执行同步系统调用,此时会阻塞M1 。
文章插图
图5中,调度器可以探测出M1被Goroutine-1阻塞了,此时调度器会将M1和P分开,但是Goroutine-1还是在M1上 。然后搞一个M2继续在P上运行,此时可以调度Goroutine-2继续执行 。GO会维护一个线程池只有线程池中没有M才会创建新的M,所以这种M切换是非常快的 。
文章插图
图6中,Goroutine-1的同步阻塞调用完成,此时Goroutine-1会被转移到P的本地队列中待被调度执行,此时M1会被放在线程池待下次使用 。
推荐阅读
- 工业机器人四大巨头的优劣势对比
- websocket连接太多导致服务器卡顿怎么办?一招轻松实现横向扩展
- 机器学习工程师和研究员之间,相隔的并不止薪水
- CPU处理器|芯片代工不会降价!台积电称3nm下半年量产 2025年量产2nm
- qq阅读器的功能介绍
- 太岁究竟是什么“东西”?我国科学家用精密仪器检测揭示太岁之谜
- 华为文本编辑器在哪?
- Chrome浏览器|Windows 10/11更新后:Chrome、Edge没法用!附解决办法
- 淘数据如何使用 淘宝数据采集器
- 阿里云服务器 Centos 7 搭建Git服务器