newproc1三个g分别代表什么意思?有何作用?
来源:1-4 Go 程序是怎么跑起来的
非晓为骁
2021-06-24 22:52:37
go func(){
}()
这个调的是newproc,newproc调newproc1会传进去一个g。但是newproc1里面有3个g,分别是图里面的1,2,3,最后调度的是2,这是为什么呢?为什么不是就是在对3进行初始化操作?
4是不是全都是在初始化g?
1回答
newproc1 是从 newproc 进来的
func newproc(siz int32, fn *funcval) { argp := add(unsafe.Pointer(&fn), sys.PtrSize) gp := getg() pc := getcallerpc() systemstack(func() { newproc1(fn, argp, siz, gp, pc) }) }
要注意到这里有个 systemstack 的动作,这个是从用户 g 切换到 g0 栈来执行函数的,
所以在 newproc1 中 getg 得到的 _g_ 是 g0,这个可以在 delve 里验证:
(dlv) l > runtime.newproc1() /usr/local/go/src/runtime/proc.go:3451 (PC: 0x10334da) Warning: debugging optimized function 3446: // at argp. callerpc is the address of the go statement that created 3447: // this. The new g is put on the queue of g's waiting to run. 3448: func newproc1(fn *funcval, argp unsafe.Pointer, narg int32, callergp *g, callerpc uintptr) { 3449: _g_ := getg() 3450: =>3451: if fn == nil { 3452: _g_.m.throwing = -1 // do not dump full stacks 3453: throw("go of nil func value") 3454: } 3455: acquirem() // disable preemption because it can be holding p in a local var 3456: siz := narg (dlv) p _g_ == _g_.m.g0 true
callergp 指的是创建这个 goroutine 的原始的那个用户 g,
你图上的 2 才是 newproc1 真正创建出来的新 g,
只不过 g 结构体本身有复用,要用 gfget 去找缓存
中间的代码确实是初始化代码。
相似问题