1 回答
TA贡献1876条经验 获得超7个赞
所以我花了一些时间研究这个主题,现在可以尝试回答我自己的问题。整个 goroutine 生命周期变得更加复杂:
新的 goroutine 在一个名为 的特殊 goroutine 中创建
g0
,它是线程的主 goroutine。任何对 的调用都会go func
将堆栈从调用它的当前 Goroutine 更改为g0
(这是在 中完成的proc.go:newproc
)。当创建 goroutine 时(在 中),它的堆栈(和/或程序计数器,PC)以看起来像是由函数调用的
proc.go:newproc1
方式构建。这样做是为了保证当 goroutine 完成并返回时,它会返回到.goexit
goexit
当
schedule
调用 并选择运行一个 goroutine 时,该execute
函数将执行它(== 通过gogo
汇编函数跳转到其地址)。Goroutine 完成后,它返回到
goexit
在汇编中实现的函数。该汇编函数调用
proc.go:goexit1
(不确定为什么需要汇编中的这个额外步骤)。该
goexit1
函数将当前堆栈更改为g0
. 这是通过调用mcall
(“机器线程调用”)来完成的,它执行参数中接收到的任何函数。在这种情况下,提供给的函数mcall
是goexit0
。在汇编中实现的 跳转到的堆栈帧 (SP)
mcall
的地址并执行to 。g0
CALL
goexit0
该
goexit0
函数在 的上下文中执行g0
。它将一个已完成的 goroutine 放入空闲 goroutine 列表中,并释放其堆栈(如果之前已增加)。然后再次
goexit0
调用schedule
,选择一个 goroutine 来运行,所以我们回到步骤 3。
所以这里确实似乎没有递归。调度的 goroutine 本身从不调用schedule
:这是由一个特殊的 goroutine 完成的g0
。我仍然不确定我是否捕获了所有细节,因此欢迎评论和其他答案。
- 1 回答
- 0 关注
- 96 浏览
添加回答
举报