【golang源码分析】并发模型MPG

1 MPG并发模型

1.1 MPG 概念

  • M 代表着一个内核线程 一个M就是一个内核线程,goroutine就是跑在M之上的
  • P 代表着(Processor)处理器 它的主要用途就是用来执行goroutine的,所以它也维护了一个可运行的goroutine队列,和自由的goroutine队列,里面存储了所有需要它来执行的goroutine。
  • G 代表着goroutine 实际的数据结构(就是你封装的那个方法),并维护者goroutine 需要的栈、程序计数器以及它所在的M等信息。
  • Seched 代表着一个调度器 它维护有存储空闲的M队列和空闲的P队列,可运行的G队列,自由的G队列以及调度器的一些状态信息等。

1.2 调度算法形象解释(来源:https://zhuanlan.zhihu.com/p/27328476)

【golang源码分析】并发模型MPG_第1张图片

 “土拨鼠” 代表一个 M,“小车”代表 P,“砖块” 代表一个 G

这个特殊的“土拨鼠” 就是这个工厂的管理员,也就是Seched(调度器)

每个新的goroutine都会维护这自己的栈,当程序启动的时候,调度器会创建第一个goroutine,首先,按照图片上的描述,管理员(Seched)找来土拨鼠(M) 并分配给土拨鼠(M)一个小车(P),土拨鼠开始推车小车拿走一批砖,(我们称这些砖被放在本地p可运行的G队列),这个土拨鼠就这么认真努力的开始完成自己的工作,有一天你在程序中提高一下程序的并发处理能力,创造了很多的砖(G),这时候,这么多的砖块(G)已经不够这些土拨鼠去处理了,于是调度器,就是去仓库里面找到空闲的土拨鼠,如果没有就创造一个土拨鼠,当工厂管理员发现,有个土拨鼠处理的很慢,这个时候就会让他去处理,但需要让出小车,调度器会找到一个新的土拨鼠去处理这个推车上的G,当土拨鼠处理完这些G的时候就需要调度器可运行的G队列总去找,当土拨鼠实在找不到goroutine就去别人的小车中枪走一半,如果多次都抢不到,那么土拨鼠就丢弃小车回到仓库里面睡觉(sleep)去了,如果土拨鼠赶上了系统调用或者网络的IO,那么土拨鼠就等待他,这时候也不能让这个土拨鼠来阻碍其他的砖(G)的运行,这时候调度器就会找来新的土拨鼠去完成剩余的工作,这时候,新的土拨鼠就会抢走车去工作 了,当这个土拨鼠的任务完成了时候发现自己的小车已经被别人抢跑了,这个土拨鼠没有什么事情,就回到仓库里面睡觉(sleep)去了。

2 runtime源码分析

2.1 go程序启动流程

在文件runtime/proc.go注释有go程序的启动流程

// The bootstrap sequence is:
//
//	call osinit
//	call schedinit
//	make & queue new G
//	call runtime·mstart
//
// The new G calls runtime·main.

参考https://zhuanlan.zhihu.com/p/27328476

 

你可能感兴趣的:(Golang)