GMP

含义

Goroutine的并发编程模型基于GMP模型,简要解释一下GMP的含义:

G:表示goroutine,每个goroutine都有自己的栈空间,定时器,初始化的栈空间在2k左右,空间会随着需求增长。

M:抽象化代表内核工作线程,记录内核线程栈信息,当goroutine调度到线程时,使用该goroutine自己的栈信息。

P:代表调度器,负责调度goroutine到M,维护一个本地goroutine队列,M从P上获得goroutine并执行,同时还负责部分内存的管理。

模型

从大体看一下GMP模型。

M代表一个工作线程,在M上有一个P和G绑定,P是绑定到M上的,G是通过P的调度获取的,在某一时刻,一个M上只有一个G(g0除外)。在P上拥有一个G队列,里面是已经就绪的G,是可以被调度到线程栈上执行的协程,称为运行队列。

接下来看一下程序中GMP的分布。

​ 每个进程都有一个全局的G队列,也拥有P的本地执行队列,同时也有不在运行队列中的G。如正处于channel的阻塞状态的G,还有脱离P绑定在M的(系统调用)G,还有执行结束后进入P的gFree列表中的G等等,接下来列举一下常见的几种状态。

状态汇总

G状态

G的主要几种状态:

本文基于Go1.13,具体代码见(<GOROOT>/src/runtime/runtime2.go)

_Gidle:刚刚被分配并且还没有被初始化,值为0,为创建goroutine后的默认值

_Grunnable: 没有执行代码,没有栈的所有权,存储在运行队列中,可能在某个P的本地队列或全局队列中(如上图)。

_Grunning: 正在执行代码的goroutine,拥有栈的所有权(如上图)。

_Gsyscall:正在执行系统调用,拥有栈的所有权,与P脱离,但是与某个M绑定,会在调用结束后被分配到运行队列(如上图)。

_Gwaiting:被阻塞的goroutine,阻塞在某个channel的发送或者接收队列(如上图)。

_Gdead: 当前goroutine未被使用,没有执行代码,可能有分配的栈,分布在空闲列表gFree,可能是一个刚刚初始化的goroutine,也可能是执行了goexit退出的goroutine(如上图)。

_Gcopystac:栈正在被拷贝,没有执行代码,不在运行队列上,执行权在

_Gscan : GC 正在扫描栈空间,没有执行代码,可以与其他状态同时存在

P的状态

_Pidle :处理器没有运行用户代码或者调度器,被空闲队列或者改变其状态的结构持有,运行队列为空

_Prunning :被线程 M 持有,并且正在执行用户代码或者调度器(如上图)

_Psyscall:没有执行用户代码,当前线程陷入系统调用(如上图)

_Pgcstop :被线程 M 持有,当前处理器由于垃圾回收被停止

_Pdead :当前处理器已经不被使用

M的状态

自旋线程(休眠状态):处于运行状态但是没有可执行G的线程,数量最多为GOMAXPROC,若是数量大于GOMAXPROC就会进入休眠。

非自旋线程(非休眠状态):处于运行状态有可执行goroutine的线程。

调度场景

Channel阻塞:当goroutine读写channel发生阻塞时候,会调用gopark函数,该G会脱离当前的M与P,调度器会执行schedule函数调度新的G到当前M。可参考上一篇文章channel探秘。

系统调用:当某个G由于系统调用陷入内核态时,该P就会脱离当前的M,此时P会更新自己的状态为Psyscall,M与G互相绑定,进行系统调用。结束以后若该P状态还是Psyscall,则直接关联该M和G,否则使用闲置的处理器处理该G。

系统监控:当某个G在P上运行的时间超过10ms时候,或者P处于Psyscall状态过长等情况就会调用retake函数,触发新的调度。

主动让出:由于是协作式调度,该G会主动让出当前的P,更新状态为Grunnable,该P会调度队列中的G运行。

总结

runtime 准备好 G, M, P, 然后 M 绑定 P, M 从各种队列中获取 G, 切换到 G 的执行栈上并执行 G 上的任务函数,调用 goexit 做清理工作并回到 M, 如此反复。

GMP的更多相关文章

  1. GCC 源码编译 mpc mprf gmp 不用make(否则会有lib/libgmp.so: could not read symbols: File in wrong format等错误)

    错误信息: lib/libgmp.so: could not read symbols: File in wrong formatcollect2: error: ld returned 1 exit ...

  2. Php GMP

    GMP是The GNU MP Bignum Library,是一个开源的数学运算库,它可以用于任意精度的数学运算,包括有符号整数.有理数和浮点数.它本身并没有精度限制,只取决于机器的硬件情况. 本函数 ...

  3. gcc configure: error: Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0

    从svn checkout svn://gcc.gnu.org/svn/gcc/trunk拿了GCC的最新代码,打算编译了学东西习学习C++ 11的东西,结果在configure的时候出现例如以下问题 ...

  4. GMP大法教你重新做人(从入门到实战)

    一.引言 GMP(The GNU Multiple Precision Arithmetic Library)又叫GNU多精度算术库,是一个提供了很多操作高精度的大整数,浮点数的运算的算术库,几乎没有 ...

  5. 深入Golang调度器之GMP模型

    前言 随着服务器硬件迭代升级,配置也越来越高.为充分利用服务器资源,并发编程也变的越来越重要.在开始之前,需要了解一下并发(concurrency)和并行(parallesim)的区别. 并发:  逻 ...

  6. Build GMP on 64bit Windows

    1.MSYS2 环境搭建 1.1.安装 msys2 的主页地址: http://www.msys2.org/ 下载32位或64位,我这里 下载了64位 msys2-x86_64-20161025.ex ...

  7. 大数高精度计算库gmp简介

    1.编译安装,我用的ubuntu18.04 $sudo apt-get install m4 //默认没安装,gmp用这个 $tar -jvxf gmp-.tar.bz2 //解压 $cd gmp- ...

  8. 记录一次在centos下使用gmp的悲伤

    有个作业是需要在linux下做的,并且需要用到gmp这个 library : 我使用的是虚拟机centos7.很久没碰过linux了,忘得差不多了,一点点百度出来的 1. 首先检查是否已存在gmp库 ...

  9. 高精度运算库gmp

    网址:www.gmplib.org 我下载的是 6.1.2版本:https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2 执行操作如下: 1. tar -jv ...

  10. GCC升级问题解决:configure: error: Building GCC requires GMP 4.2+, MPFR 2.4.0+ and MPC 0.8.0+.,mpfr2.4.0

    如果遇到类似问题: configure: error: Building GCC requires GMP 4.2+, MPFR 2.4.0+ and MPC 0.8.0+.,mpfr2.4.0 解决 ...

随机推荐

  1. C# app.config 保存和读取例子

    保存: Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath); if ...

  2. 【摘抄】疑问chatterbot

    ChatterBot使用哪种机器学习? -------------------------------------------------- -  简而言之,ChatterBot使用了许多不同的机器学 ...

  3. Natasha 4.0 探索之路系列(二) "域"与插件

    域与ALC 在 Natasha 发布之后有不少小伙伴跑过来问域相关的问题, 能不能兼容 AppDomain, 如何使用 AppDomain, 为什么 CoreAPI 阉割了 AppDomain 等一系 ...

  4. 开发者的瑞士军刀「GitHub 热点速览 v.22.04」

    Swiss Army knife 可以说是本周的关键词了,多个项目采用该词来描述它的特性:像是能全方位解决浏览器"网络"操作的 CyberChef 方便你进行数据加密.解编码,还有 ...

  5. 黑客是如何通过开放的Redis服务入侵服务器的

    0x00 简要说明 百度百科:Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-V ...

  6. 【程序5】输入三个整数x,y,z,请把这三个数由小到大输出

    我自己写的: x = int(input('x:')) y = int(input('y:')) z = int(input('z:')) L = [x,y,z] print(sorted(L)) 官 ...

  7. Vue+webpack配置实现多页面应用开发

    为什么要配置多页面开发? · 由于单页面应用不利于SEO,对于某些资讯类网站不够友好,而多页面则能够更优的解决此问题. · 传统的多页面开发模式(如java的jsp等) 前后端耦合性大,开发效率低,代 ...

  8. plsql 带参数的游标

    -- 带参数的游标 -- cursor c(no emp.deptno%type) is select * from emp where deptno=no; 参数的起名 不要和表中的列名相同! -- ...

  9. 测试开发实战[提测平台]20-图表G2Plot在项目的实践实录

    微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. G2Plot项目应用 上一篇<提测平台19-Echarts图表在项目的实践>讲解了Echarts的图表应用,此篇来看下开箱即用 ...

  10. rabbitMq使用guest登录不上的问题总结

    自己mac电脑上的mq在电脑关机(直接按电源键关机),在开机后,rabbitMq连不上了,报500错误. 1.在使用brew uninstall rabbitmq --force后; 2.我手动安装了 ...