Blog.8 runtime中P的理解

P是在Go1.1引入的概念,初始默認等於CPU核的數量。P只是一個邏輯概念,跟CPU也沒有任何關係。ide

源碼go/1.13.4/libexec/src/runtime/proc.go中對P的註釋以下:oop

// P - processor, a resource that is required to execute Go code.
// M must have an associated P to execute Go code, however it can be
// blocked or in a syscall w/o an associated P.

再經過源碼go/1.13.4/libexec/src/runtime/runtime2.go來簡要了解一下P在調度過程當中的狀態變化:ui

const (
    // P status
    _Pidle = iota
    _Prunning
    _Psyscall
    _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
)

經過調整GOMAXPROCS能夠控制P的狀態,_Pdead專門來講明這一點。this

P的結構體字段中,能夠進一步瞭解P中存儲的資源,源碼go/1.13.4/libexec/src/runtime/runtime2.goatom

type p struct {
        id          int32
        status      uint32 // one of pidle/prunning/...
        link        puintptr
        schedtick   uint32     // incremented on every scheduler call
        syscalltick uint32     // incremented on every system call
        sysmontick  sysmontick // last tick observed by sysmon
        m           muintptr   // back-link to associated m (nil if idle)
        mcache      *mcache
        raceprocctx uintptr

        deferpool    [5][]*_defer // pool of available defer structs of different sizes (see panic.go)
        deferpoolbuf [5][32]*_defer

        // Cache of goroutine ids, amortizes accesses to runtime·sched.goidgen.
        goidcache    uint64
        goidcacheend uint64

        // Queue of runnable goroutines. Accessed without lock.
        runqhead uint32
        runqtail uint32
        runq     [256]guintptr
        // runnext, if non-nil, is a runnable G that was ready'd by
        // the current G and should be run next instead of what's in
        // runq if there's time remaining in the running G's time
        // slice. It will inherit the time left in the current time
        // slice. If a set of goroutines is locked in a
        // communicate-and-wait pattern, this schedules that set as a
        // unit and eliminates the (potentially large) scheduling
        // latency that otherwise arises from adding the ready'd
        // goroutines to the end of the run queue.
        runnext guintptr

        // Available G's (status == Gdead)
        gFree struct {
                gList
                n int32
        }

        sudogcache []*sudog
        sudogbuf   [128]*sudog

        tracebuf traceBufPtr
         // traceSweep indicates the sweep events should be traced.
        // This is used to defer the sweep start event until a span
        // has actually been swept.
        traceSweep bool
        // traceSwept and traceReclaimed track the number of bytes
        // swept and reclaimed by sweeping in the current sweep loop.
        traceSwept, traceReclaimed uintptr

        palloc persistentAlloc // per-P to avoid mutex

        _ uint32 // Alignment for atomic fields below

        // Per-P GC state
        gcAssistTime         int64    // Nanoseconds in assistAlloc
        gcFractionalMarkTime int64    // Nanoseconds in fractional mark worker (atomic)
        gcBgMarkWorker       guintptr // (atomic)
        gcMarkWorkerMode     gcMarkWorkerMode

        // gcMarkWorkerStartTime is the nanotime() at which this mark
        // worker started.
        gcMarkWorkerStartTime int64

        // gcw is this P's GC work buffer cache. The work buffer is
        // filled by write barriers, drained by mutator assists, and
        // disposed on certain GC state transitions.
        gcw gcWork

        // wbBuf is this P's GC write barrier buffer.
        //
        // TODO: Consider caching this in the running G.
        wbBuf wbBuf

        runSafePointFn uint32 // if 1, run sched.safePointFn at next safe point

        pad cpu.CacheLinePad
}

字段中mcache再單獨說明一下,源碼go/1.13.4/libexec/src/runtime/mcache.go:spa

// Per-thread (in Go, per-P) cache for small objects.
// No locking needed because it is per-thread (per-P).
//
// mcaches are allocated from non-GC'd memory, so any heap pointers
// must be specially handled.
//
//go:notinheap

mcache反映了對象的建立策略:小對象。code

相關文章
相關標籤/搜索