Last active
November 17, 2019 12:56
-
-
Save yanjinbin/dd6e5521af43366d15211eb5a000b39c to your computer and use it in GitHub Desktop.
G和P的状态
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// defined constants | |
const ( | |
// G status | |
// | |
// Beyond indicating the general state of a G, the G status | |
// acts like a lock on the goroutine's stack (and hence its | |
// ability to execute user code). | |
// | |
// If you add to this list, add to the list | |
// of "okay during garbage collection" status | |
// in mgcmark.go too. | |
// | |
// TODO(austin): The _Gscan bit could be much lighter-weight. | |
// For example, we could choose not to run _Gscanrunnable | |
// goroutines found in the run queue, rather than CAS-looping | |
// until they become _Grunnable. And transitions like | |
// _Gscanwaiting -> _Gscanrunnable are actually okay because | |
// they don't affect stack ownership. | |
// _Gidle means this goroutine was just allocated and has not | |
// yet been initialized. | |
_Gidle = iota // 0 | |
// _Grunnable means this goroutine is on a run queue. It is | |
// not currently executing user code. The stack is not owned. | |
_Grunnable // 1 | |
// _Grunning means this goroutine may execute user code. The | |
// stack is owned by this goroutine. It is not on a run queue. | |
// It is assigned an M and a P. | |
_Grunning // 2 | |
// _Gsyscall means this goroutine is executing a system call. | |
// It is not executing user code. The stack is owned by this | |
// goroutine. It is not on a run queue. It is assigned an M. | |
_Gsyscall // 3 | |
// _Gwaiting means this goroutine is blocked in the runtime. | |
// It is not executing user code. It is not on a run queue, | |
// but should be recorded somewhere (e.g., a channel wait | |
// queue) so it can be ready()d when necessary. The stack is | |
// not owned *except* that a channel operation may read or | |
// write parts of the stack under the appropriate channel | |
// lock. Otherwise, it is not safe to access the stack after a | |
// goroutine enters _Gwaiting (e.g., it may get moved). | |
_Gwaiting // 4 | |
// _Gmoribund_unused is currently unused, but hardcoded in gdb | |
// scripts. | |
_Gmoribund_unused // 5 | |
// _Gdead means this goroutine is currently unused. It may be | |
// just exited, on a free list, or just being initialized. It | |
// is not executing user code. It may or may not have a stack | |
// allocated. The G and its stack (if any) are owned by the M | |
// that is exiting the G or that obtained the G from the free | |
// list. | |
_Gdead // 6 | |
// _Genqueue_unused is currently unused. | |
_Genqueue_unused // 7 | |
// _Gcopystack means this goroutine's stack is being moved. It | |
// is not executing user code and is not on a run queue. The | |
// stack is owned by the goroutine that put it in _Gcopystack. | |
_Gcopystack // 8 | |
// _Gscan combined with one of the above states other than | |
// _Grunning indicates that GC is scanning the stack. The | |
// goroutine is not executing user code and the stack is owned | |
// by the goroutine that set the _Gscan bit. | |
// | |
// _Gscanrunning is different: it is used to briefly block | |
// state transitions while GC signals the G to scan its own | |
// stack. This is otherwise like _Grunning. | |
// | |
// atomicstatus&~Gscan gives the state the goroutine will | |
// return to when the scan completes. | |
_Gscan = 0x1000 | |
_Gscanrunnable = _Gscan + _Grunnable // 0x1001 | |
_Gscanrunning = _Gscan + _Grunning // 0x1002 | |
_Gscansyscall = _Gscan + _Gsyscall // 0x1003 | |
_Gscanwaiting = _Gscan + _Gwaiting // 0x1004 | |
) | |
const ( | |
// P status | |
// _Pidle means a P is not being used to run user code or the | |
// scheduler. Typically, it's on the idle P list and available | |
// to the scheduler, but it may just be transitioning between | |
// other states. | |
// | |
// The P is owned by the idle list or by whatever is | |
// transitioning its state. Its run queue is empty. | |
_Pidle = iota | |
// _Prunning means a P is owned by an M and is being used to | |
// run user code or the scheduler. Only the M that owns this P | |
// is allowed to change the P's status from _Prunning. The M | |
// may transition the P to _Pidle (if it has no more work to | |
// do), _Psyscall (when entering a syscall), or _Pgcstop (to | |
// halt for the GC). The M may also hand ownership of the P | |
// off directly to another M (e.g., to schedule a locked G). | |
_Prunning | |
// _Psyscall means a P is not running user code. It has | |
// affinity to an M in a syscall but is not owned by it and | |
// may be stolen by another M. This is similar to _Pidle but | |
// uses lightweight transitions and maintains M affinity. | |
// | |
// Leaving _Psyscall must be done with a CAS, either to steal | |
// or retake the P. Note that there's an ABA hazard: even if | |
// an M successfully CASes its original P back to _Prunning | |
// after a syscall, it must understand the P may have been | |
// used by another M in the interim. | |
_Psyscall | |
// _Pgcstop means a P is halted for STW and owned by the M | |
// that stopped the world. The M that stopped the world | |
// continues to use its P, even in _Pgcstop. Transitioning | |
// from _Prunning to _Pgcstop causes an M to release its P and | |
// park. | |
// | |
// The P retains its run queue and startTheWorld will restart | |
// the scheduler on Ps with non-empty run queues. | |
_Pgcstop | |
// _Pdead means a P is no longer used (GOMAXPROCS shrank). We | |
// reuse Ps if GOMAXPROCS increases. A dead P is mostly | |
// stripped of its resources, though a few things remain | |
// (e.g., trace buffers). | |
_Pdead | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment