当生成goroutine时恢复调用堆栈

huangapple go评论82阅读模式
英文:

Recover call stack when spawning goroutines

问题

以下是翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

以下是要翻译的内容:

英文:

The following

func a() { b() }
func b() { c() }
func c() { d() }
func d() {
	pc := make([]uintptr, 10)
	n := runtime.Callers(1, pc)
	if n == 0 {
		return
	}

	frames := runtime.CallersFrames(pc[:n])

	for {
		frame, more := frames.Next()

		fmt.Println(frame.Function)

		if !more {
			break
		}
	}

}

func main() {
	a()
    // The reason for this sleep will become apparent in an incoming example
    // where we spawn a goroutine and do not explicitely wait for it to finish
	time.Sleep(time.Second)
}

outputs

main.d
main.c
main.b
main.a
main.main
runtime.main
runtime.goexit

as I expected. I am facing a situation where function c is called in a separate goroutine

func b() { go c() }

In such cas it outputs

main.d
main.c
runtime.goexit

, while I wished it to outpout the same as above.

Is there a solution to this problem? Maybe something to capture a call stack and pass it to function d? Note that performance will matter and I wish to avoid processing the stack beforehand as in my real life example, d might or might not need to trigger the call to runtime.Callers.

答案1

得分: 2

没有解决方案。当你将一个函数作为另一个goroutine启动时,它将完全独立于启动goroutine运行。启动者可能继续执行或完全结束/终止。出于明显的原因,"启动"堆栈不会被保留。

因此,除非你在启动另一个goroutine时显式地查询、保留/传递堆栈,否则你将失去它。

注意:可以检测一个函数是否作为goroutine启动,如果是的话,你可以限制只在这种情况下查询和保留堆栈,而不是所有情况下都这样做。有关详细信息,请参见https://stackoverflow.com/questions/56702183/check-if-function-is-being-called-as-goroutine-or-not/56702614#56702614。

英文:

There is no solution. When you launch a function as another goroutine, it will run completely independent from the launching goroutine. The launcher may move on or completely finish / terminate. The "starting" stack is not retained for obvious reasons.

So unless you explicitly query and retain / pass the stack yourself when launching another goroutine, you'll lose it.

Note: it's possible to detect if a function is launched as a goroutine or not, and you could limit querying and retaining the stack only if so, and not in all cases. For details, see https://stackoverflow.com/questions/56702183/check-if-function-is-being-called-as-goroutine-or-not/56702614#56702614.

huangapple
  • 本文由 发表于 2022年6月8日 20:12:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/72545499.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定