本文主要是介绍goroutine调度策略,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Golang
的调度器采用M:N
调度模型,其中M代表用户级别的线程(也就是goroutine
),而N代表的事内核级别的线程。Go
调度器的主要任务就是N个OS线程上调度M个goroutine
。这种模型允许在少量的OS线程上运行大量的goroutine
。
Go
调度器使用了三种队列来管理goroutine
- 全局队列(Global Queue):此队列中包含了所有刚创建的
goroutine
。 - 本地队列(Local Queue):每个P(Processor,处理器)都有一个本地队列,P会有限从本地队列中取出
goroutine
来执行。 - 网络轮循器(Netpoller):此队列中包含了所有在等待网络时间(如IO操作)的
goroutine
。当网络事件就绪时,对应的goroutine
会被放入到全局队列中,等待被P取出。
Go
的调度器采用了工作窃取(Work Stealing)和手动抢占(Preemption)的策略
- 工作窃取:当一个P的本地队列中没有
goroutine
时,它会尝试从全局队列或其他P的本地队列中窃取goroutine
来执行。 - 手动抢占:为了防止一个
goroutine
长时间占用P而导致其他goroutine
饿死,Go
的调度器会定期地进行抢占操作。在Go 1.14
之前,Go
的调度器只在函数调用时才会进行抢占,从Go 1.14
开始引入了异步抢占,即允许在任何安全点进行抢占。
这种调度模型和策略使得Go
语言可以有效地利用硬件资源,处理大量的并发任务,同时也为复杂的并发编程提供了简介的语言级别的支持。
最后给大家推荐一个LinuxC/C++高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习C/C++后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04uB
这篇关于goroutine调度策略的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!