go 调度流程
2018-03-14 10:37:09 36 举报
goroutine 生命周期
作者其他创作
大纲/内容
N
Y()
entersyscall
获取到G
syscall
执行lockedG
RawSysCall
go func()
从P本地队列获取G任务(P.runnext - P.runq)
这是线程的入口
goexit
转移一批G到P本地
Y
让当前M绑定P并执行
是否是阻塞系统调用
放进全局队列
进入系统调用
放进P空闲队列
P本地队列是否已满
N(阻塞性系统调用)
RUNABLE
有可能已经被sysmon抢走
schedule
* 如果有空闲P* 没有M处于自旋等待P或G*非main goroutine
entersyscallblock
检查Sched的sysmonwait是否为0
系统调用
全局\"已释放G\"链表是否存在
能否保存在P.runnext
IDLE
唤醒M并绑定空闲P进行执行
有没有空闲P
M是操作系统线程的抽象
runtime.mstart
唤醒M出来执行任务
当前M对于的P中是否有\"已释放G\"
Dead
复用G
SysCall
Running
新建M(newm)并绑定P
(复用G)
schedue
获取G结构体
捡到一个lockedG
放入当前P的本地队列(P.runq)
newproc
是否是lockedm?
创建新的G结构体
进入睡眠并等待唤醒
runtime·notewakeup/确保sysmon运行
初始化G(栈/上下文/运行函数/id)
睡眠当前M并调用schedule
DEAD
Y(复用G)
保存执行现场(PC/SP)
有锁
进入运行队列
Runable
置空M/P的Mache/进入系统调用的M不需要Mache
handoffp切换P
将G放回P的复用(free)队列
执行(execute)G
exitsyscall
是否有空闲M
M还保留P的引用
转移一批G到全局G队列(Sched.runq)
放进P.runnext
收藏
0 条评论
下一页