Go语言-GPM内存模型浅析
相关知识基础
什么是多线程
多线程一般指的是操作系统级别的多线程。指的是任务的调度不由我们手动触发,而是通过一些程序命令,把任务交给系统来进行调度,而系统怎么去调度这些任务,我们并不关心。只需要告诉系统哪些任务是优先的,哪些是不怎么重要的,系统就会根据这种优先级去分配处理任务。
并发和并行
并发:宏观上面的同时执行,实际上是指任务在同一时段能够共同被调度的一种描述。
并行:同一时刻的执行,指任务能够在同一个时刻被调度同时执行。
具体在计算机中的体现呢?
我们已经知道多线程是任务放入后台由系统进行调度,那么是由谁真正的来执行的呢?
实际上就是由计算机的cpu来进行调度。我们常说的多核,直接理解就是一个cpu在同一时刻可以干多少件事。
所以我们可以抽象的理解为,任务的真正执行是cpu的"核",这一个小弟来干的。
进一步理解并行和并发:
并发:
- 任务能够放入后台被cpu去分配调度,不用我们手动触发,这样的多线程工作模式就是并发。
并行:- 任务可并发,即任务被放入后台由cpu进行调度。
- cpu有多个"核"小弟,能够同时调度多个任务分配给每一个"核"小弟去执行,这就是并行。
GPM内存模型
参考图例
解析
解析
M:M是go进程真正被cpu调度的线程,它会关联一个任务队列P。在CPU调度M的时候,M从P里面去找到任务G去被调度执行。
P:任务队列。它会关联一个M。当前的任务会到M去执行,待M被cpu调度,就会从P里面调度任务执行。
G:每一个goroutine产生的任务,可以说就是go进程里面的真正的"线程"。区别在于这一个任务是由go的后台进行调度的,而不是由cpu直接进行调度的。
详细流程
- 每创建一个G任务,优先创建一个P进行存储,P会进一步创建一个M去调度执行。P-M相互绑定的。
- P可以理解为go进程的一个cpu核,它负责去调度G任务。而M与P进行对接,M真正的被系统cpu核调度。
- P存在上限,当P达到上限时,新增任务开始进入waiting状态,进入等待队列。
- 当P的任务队列结束之后,会去找寻全局的G,直到所有的任务结束。
以上内容属粗略理解,具体调度可参照golang中文网,或深入了解go源码。