关于newproc问题

来源:1-4 Go 程序是怎么跑起来的

东泽XD

2021-05-20 17:34:41

Q1:newproc使用systemstack切换的栈空间是谁的栈空间(在调度模型中有对应的对象么)?

Q2:若在systemstack环境下使用getg获取的是g0,为什么要用g0获取P而不是g?(不是都关联着同一个M么?※)

type m struct { type m struct {

...    ​    ​    ​    ​    ​...

g0 *g    ​    ​    ​    ​m *m

curg *g    ​    ​    ​    ​...

...    ​    ​    ​    ​  }

}

http://img.mukewang.com/climg/60a627ab094d2c3a04600336.jpg

相关截图:

老师在群里给出的图

http://img.mukewang.com/climg/60a6277b08e9381607280350.jpg

写回答

1回答

Xargin

2021-05-20

Q1:newproc使用systemstack切换的栈空间是谁的栈空间(在调度模型中有对应的对象么)?

systemstack 函数调用,会切到 m 的 g0 栈上,systemstack 返回的时候,会切回原来的 g 栈

Q2:若在systemstack环境下使用getg获取的是g0,为什么要用g0获取P而不是g?(不是都关联着同一个M么?※)

我看这两个值是一样的,可以调试打断点输出出来看看

> runtime.newproc1() /usr/local/go/src/runtime/proc.go:3266 (PC: 0x1031dea)
Warning: debugging optimized function
  3261:	// at argp. callerpc is the address of the go statement that created
  3262:	// this. The new g is put on the queue of g's waiting to run.
  3263:	func newproc1(fn *funcval, argp *uint8, narg int32, callergp *g, callerpc uintptr) {
  3264:		_g_ := getg()
  3265:
=>3266:		if fn == nil {
  3267:			_g_.m.throwing = -1 // do not dump full stacks
  3268:			throw("go of nil func value")
  3269:		}
  3270:		acquirem() // disable preemption because it can be holding p in a local var
  3271:		siz := narg
(dlv) p callergp.m.p
824633877760
(dlv) p _g_.m.p
824633877760
(dlv)


不过我猜测,可能在创建 newproc 的时候,可能会因为抢占调度之类的原因,导致创建出来的 g 和原来的不在一个 P 上了?但是不太好验证

1

Go高级工程师实战营

慕课网与 GoCN 社区官方联手打造,定义行业Go高级人才培养标准,4个月,快速晋升为P6+/D7级高级人才。

458 学习 · 266 问题

查看课程