首页后端开发GOGo调度系列--GMP状态流转(四)(go gmp调度)

Go调度系列--GMP状态流转(四)(go gmp调度)

时间2023-04-03 15:06:57发布访客分类GO浏览687
导读:前言在GMP中各个元素在调度器的调度下其实有各种不同的状态转换,比如goroutine就定义了比如_Gidle、_Grunnable、_Grunning、_Gsyscall和_Gwaiting这些状态,在不同的场景中实现这些状态进行不同的转...

前言

在GMP中各个元素在调度器的调度下其实有各种不同的状态转换,比如goroutine就定义了比如_Gidle、_Grunnable、_Grunning、_Gsyscall和_Gwaiting这些状态,在不同的场景中实现这些状态进行不同的转换。

G状态转换

goroutine的状态在runtime/runtime2.go中,_Gidle中被定义为iota,声明为一个无类型整数序号 0,其他定义的枚举逐步进行递增。

// _Gidle means this goroutine was just allocated and has not
// yet been initialized.
_Gidle = iota // 0

_Grunnable // 1
...

Goroutine 枚举的这些状态有以下几种:

  1. _Gidle = 0 goroutine刚刚被分配并且还没有被初始化
  2. _Grunnable = 1 没有执行代码,没有栈的所有权,存储在运行队列中
  3. _Grunning = 2 可以执行代码,拥有栈的所有权,被赋予了内核线程 M 和处理器 P
  4. _Gsyscall = 3 正在执行系统调用,没有执行用户代码,拥有栈的所有权,被赋予了内核线程 M 但是不在运行队列上
  5. _Gwaiting = 4 由于运行时而被阻塞,没有执行用户代码并且不在运行队列上,但是可能存在于 Channel 的等待队列上。若需要时执行ready()唤醒
  6. _Gdead = 6 没有被使用,可能刚刚退出,或在一个freelist;也或者刚刚被初始化;没有执行代码,可能有分配的栈也可能没有;G和分配的栈(如果已分配过栈)归刚刚退出G的M所有或从free list 中获取

其中有几个状态是不用去理会的:_Genqueue_unused(目前未使用)_Gcopystack=8 (不在运行队列上) _Gpreempted=9 (没有执行用户代码) _Gscan=10 GC (没有执行代码,可以与其他状态同时存在 )

G状态流转

M状态转换

M本身其实是无状态的,不过我们可以根据M是否空闲,执行代码,休眠等这些情况将M的列举一些当前行为。

  1. 自旋中:(spinning) M正在从运行队列中获取G,这个时候M拥有一个P
  2. 执行代码:M正在执行go代码,此时M拥有一个P
  3. 执行原生代码中:M正在执行原生代码或者阻塞的syscall,此时的M不会拥有P
  4. 休眠中:M发现无待运行的G时会进入休眠,并添加到空闲M链表中
M状态

P状态转换

p的底层结构和状态枚举跟g在同一个文件中,主要定义了一下几种状态:

const (
   _Pidle = iota
   _Prunning
   _Psyscall 
   _Pgcstop
   _Pdead
)

type p struct {

   id          int32
   status      uint32 // one of pidle/prunning/...与状态相关  
   ...
   runq     [256]guintptr //p本地队列 默认容量为256个G
   runnext guintptr  //下一个将要运行的G
}
    
  • Pidle:当前p尚未与任何m关联,处于空闲状态
  • Prunning:当前p已经和m关联,并且正在运行g代码
  • Psyscall:当前p正在执行系统调用
  • Pgcstop:当前p需要停止调度,一般在GC前或者刚被创建时
  • Pdead:当前p已死亡,不会再被调度
P状态流转

在P创建之初或结束gc后,会被置为Pgcstop状态,在完成初始化之后,会进入Pidel状态,进入该状态后的P可被调度器调度,当P与某个M相关联时,会进入到Prunning状态,当其执行系统调用时,会进入到Psyscall状态,当P应为全局P列表的缩小而被删除时会进入Pdead状态,不会再进行状态流转和调度。当正在执行的P由于某些原因停止调度时,会统一流转成Pidle空闲状态,等待调度,避免线程饥饿。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

go

若转载请注明出处: Go调度系列--GMP状态流转(四)(go gmp调度)
本文地址: https://pptw.com/jishu/876.html
基于Go/Grpc/kubernetes/Istio开发微服务的最佳实践尝试 - 2/3 【翻译】使用Go生成一个随机字符串(密码)(go生成随机数)

游客 回复需填写必要信息