golang学习之一:Golang 调度器 GMP 原理

写了这么多年的golang,这是我开始去整理自己的golang知识的第一篇

参考资料: Golang 调度器 GMP 原理与调度全分析 Go-GMP模型

Golang 调度器 GMP 原理与调度全分析

1、进程线程的背景

计算机程序的开发演进到协程经历了很长期的阶段

1、单进程时代

2、多进程 / 多线程时代

3、协程

协程主要解决多进程多线程时代的两大问题

  • 高内存占用:(进程虚拟内存会占用 4GB [32 位操作系统], 而线程也要大约 4MB)。在当今互联网高并发场景下,为每个任务都创建一个线程是不现实的。
  • 调度的高消耗 CPU:进程拥有太多的资源,进程的创建、切换、销毁,都会占用很长的时间,CPU 虽然利用起来了,但如果进程过多,CPU 有很大的一部分都被用来进行进程调度了。

2、golang GMP实现

Ugu3C2WSpM.jpeg

  1. 全局队列(Global Queue):存放等待运行的 G。

  2. P 的本地队列:同全局队列类似,存放的也是等待运行的 G,存的数量有限,不超过 256 个。新建 G’时,G’优先加入到 P 的本地队列,如果队列满了,则会把本地队列中一半的 G 移动到全局队列。

  3. P 列表:所有的 P 都在程序启动时创建,并保存在数组中,最多有 GOMAXPROCS(可配置) 个。

  4. M:线程想运行任务就得获取 P,从 P 的本地队列获取 G,P 队列为空时,M 也会尝试从全局队列拿一批 G 放到 P 的本地队列,或从其他 P 的本地队列偷一半放到自己 P 的本地队列。M 运行 G,G 执行之后,M 会从 P 获取下一个 G,不断重复下去。Goroutine 调度器和 OS 调度器是通过 M 结合起来的,每个 M 都代表了 1 个内核线程,OS 调度器负责把内核线程分配到 CPU 的核上执行。

原文作者:刘丹冰Aceld 转自链接:https://learnku.com/articles/41728 版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。

发布于