zoukankan      html  css  js  c++  java
  • 浅析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博客

  • 相关阅读:
    为archlinux安装mplayer
    linux与windows的文本文件之间的转换
    有关git的换行符的处理问题
    让git忽略文件模式的改变
    linux更新系统之后,删除多余的开机启动项
    关于centos更新后virtualbox无法使用的问题
    SQL 中逻辑运算符的优先级
    archlinux安装输入法需要的包及archlinux无法使用输入法的解决
    从前有座山,山里有座庙
    批量修改照片名称的shell脚本
  • 原文地址:https://www.cnblogs.com/liuqun/p/14265030.html
Copyright © 2011-2022 走看看