美文网首页
Go GPM 模型

Go GPM 模型

作者: 晚歌歌 | 来源:发表于2022-03-08 16:46 被阅读0次

    GPM 模型

    golang 在系统调度的基础上实现了自己的 goroutine 调度器,即 GPM 模型。goroutine 相比线程更加轻量,GPM 调度器效率更高,因此 go 可以有很强的并发能力


    image.png

    G:goroutine
    P:Processor,相当于 G 的CPU,数量等于 GOMAXPROC
    M:执行 G 的线程
    GPM 简单原理:

    每个 P 都有一个局部队列,负责保存待执行的 G,当局部队列满了就放到全局队列中

    每个 P 都有一个 M 绑定,正常情况下 M 从局部队列中获取 G 执行

    M 可以从其他队列偷取 G 执行(work stealing),也可以从全局队列获取 G 执行

    当 G 因系统调用(syscall)阻塞时会阻塞 M,此时 P 会和 M 解绑(hand off),并寻找新的空闲 M,若没有空闲 的M 就会新建一个 M

    当 G 因 channel 或者 network I/O 阻塞时,不会阻塞 M,M 会寻找其他 runnable 的 G;当阻塞的 G 恢复后会重新进入 runnable 进入 P 队列等待执行

    mcache(内存分配状态)位于 P,所以 G 可以跨M调度,不再存在跨 M 调度局部性差的问题

    G 是抢占调度。不像操作系统按时间片调度线程那样,Go 调度器没有时间片概念,G 因阻塞和被抢占而暂停,并且 G只能在函数调用时有可能被抢占,极端情况下如果 G 一直做死循环就会霸占一个 P 和 M,Go 调度器也无能为力。

    GODEBUG

    使用 GODEBUG 可以查看 Go 调度器的实际过程:

    #含义就是每1000ms,打印输出一次goroutine scheduler的状态
    GODEBUG=schedtrace=1000 ./goutils 
    
    #输出
    gomaxprocs:P 的数量
    
    idleprocs:空闲的 P
    
    threads:总线程数
    
    spinningthreads:自旋线程数
    
    idlethreads:空闲线程数
    
    runqueue:全局队列中 G 的数目
    
    [2 3 3 2 1 1 2 1]:局部队列中 G 的数目
    

    相关文章

      网友评论

          本文标题:Go GPM 模型

          本文链接:https://www.haomeiwen.com/subject/gtbarrtx.html