• MPG线程模型简介


    概述

    go语言中的MPG线程模型对两级线程模型进行了一定程度的改进,使它能够更加灵活的进行线程之间的调度。
    它由3个主要模块构成,如下图:

    MPG的3个主要模块以及功能,我们通过下表所示。

    模块 功能说明
    Machine 一个Machine对应一个内核线程,相当于内核线程在go语言中的映射
    Processor 一个Processor表示执行go代码片段的所必需的上下文环境,可以理解为用户代码逻辑的处理器
    Goroutine 是对go语言中代码片段的封装,其实是一种轻量级的用户线程

    为了更加形象,下面的介绍中我们会用M、P、G分别指代Machine、Processor和Goroutine。从图4-4可以看出,每一个
    M都会与一个内核线程绑定,在运行时一个M同时只绑定一个P,而P和G的关系则是一对多。在运行过程中,M和内核线程之间
    对应关系不会变化,在M的生命周期内,它只会与一个内核线程绑定,而M和P以及P和G之间的关系都是动态可变的。
    在实际的运行过程中,M和P的组合才能够为G提供有效的运行环境,而多个可执行G将会顺序排成一个队列挂在某个P上面,
    等待调度和执行,如图所示。

    上图中,M和P共同构成了一个基本的运行环境,此时G0中的代码片段处于正在运行的状态,而右边的G队列处于待执行状态。
    当没有足够的M来和P组合为G提供运行环境时,Go语言会创建新的M。在很多时候M的数量可能会比P要多。在单个go语言进程中,
    P的最大数量决定了程序的并发规模,且P的最大数量是由程序决定的。可以通过修改环境变量GOMAXPROCS和调用函数runtime.GOMAXPROCS
    来设定P的最大值。
    M和P会适时的组合和断开,以保证待执行G队列能够得到及时运行。比如说图4-5中的G0此时因为网络I/O而阻塞了M,那么P就会携带剩余的
    G投入到其他M中。这个新的M(M1)可能是新创建的,也可能是从调度器空闲M列表中获取的,这取决于此时的调度器空闲M列表中是否存在M,
    这样的机制设计也是为了避免M过多创建。运行机制如图所示

    当M对应的内核线程被唤醒时,M将会尝试为G0捕获一个P上下文,可能是从调度器的空闲P列表中获取,如果获取不成功,
    M会把G0放入到调度器的可执行G队列中,等待其他P的查找。为了保证G的均衡执行,非空闲的P运行完自身的可执行G队列后,
    会周期性从调度器的可执行G队列中获取待执行的G,甚至从其他的P的可执行G队列中掠夺G。

  • 相关阅读:
    异常处理 try catch throw(C++)
    Kubernetes轻量级日志收集系统LokiStack
    第一章.java
    第四章.选择结构(二)
    java语法
    第三章if选择结构
    第二章.数据类型变量名和运算符
    【转载】跳槽七诫
    【转载】修改shell终端提示信息
    ubuntu11.10面板上输入法图标消失解决办法
  • 原文地址:https://www.cnblogs.com/weiweivip666/p/16291535.html
Copyright © 2020-2023  润新知