• 浅析Go中的MPG模式(一)


    Goroutine(协程)
    首先了解一下协程(goroutine)这个东西
    1、Go线程(主线程,一般称为线程,有的大佬们也直接叫进程),也可理解为进程。是一个物理级线程,重量级的,非常耗费CPU资源


    2、一个线程上可以有多个协程(goroutine),协程是轻量级的线程(go对于线程进行的特殊处理)。逻辑态,消耗资源相对少。按照消耗资源可以这样排序:进程 >= 主线程 > 子线程 >= 协程


    3、Go协程特点
    (1)有独立的栈空间
    (2)共享程序堆空间
    (3)调度由用户(程序)控制
    (4)协程是轻量级的线程


    4、主线程退出了,协程即使未执行完毕也会停止,退出程序。


    MPG模式:

    1、解释一下MPG含义:
    M(Machine):操作系统的主线程
    P(Processor):协程执行需要的资源(上下文context),可以看作一个局部的调度器,使go代码在一个线程上跑,他是实现从N:1到N:M映射的关键
    G(Gorountine):协程,有自己的栈。包含指令指针(instruction pointer)和其它信息(正在等待的channel等等),用于调度。一个P下面可以有多个G


    2、**P的数量可以通过GOMAXPROCS()来设置,**他其实代表了真正的并发度,即有多少个goroutine可以同时运行。P同时也维护着G(协程)的队列(称之为runqueue进程队列)。Go代码中的M每有一个语句被执行,P就在末尾加入一个G(从runqueue队列中取出来的),在下一个调度点(P),就从runqueue队列中取出G。(图片来源于网络,太多类似的忘了在哪截的)
    在这里插入图片描述


    3、P可以在OS线程(主线程,或者是M)被阻塞时,转到另一个OS线程(M)!Go中的调度器保证有足够的线程来运行所有的P。当启用一个M0中的G0被sysCall(系统调用)的时候,M0下面的P转给另一个线程M1(可以是创建的,也可以是原本就存在的)。M1接受了P(包括P所带的runqueue的队列里面所有状态的G,但不包括已经被syscall的G0),继续运行。而M0会等待执行syscall的G0的返回值。当G0的syscall结束后,他的主线程M0会尝试取得一个P来运行G0,一般情况下,他会从其他的M里面偷一个P过来,如果没有偷到的话就会把G0放到一个Global runqueue(全局进程队列)中,然后把自己(M0)放进线程池或者转为休眠状态。


    4、Global runqueue是各个P在运行完自己的本地的goroutine runqueue后用来拉取新goroutine的地方。P也会周期性的检查这个Global runqueue上的goroutine,否则全局runqueue上的goroutine可能得不到执行而饿死。。。
    9、当P中的runqueue队列里面的G全部执行完毕之后,他会偷取未执行完的P中的G(偷取一半)!

    上面MPG中的第3和4可以参考:Go并发原理—RyuGou博客

    Go并发原理—RyuGou博客

  • 相关阅读:
    mac 安装ROS2
    193 最长有效括号
    个人笔记
    个人笔记
    个人笔记-大佬主页
    笔记-吴恩达老师机器学习及深度学习
    个人笔记
    转载-资源链接
    枚举类型
    333333333333333333333333
  • 原文地址:https://www.cnblogs.com/liuqun/p/14265030.html
Copyright © 2020-2023  润新知