首页 >后端开发 >Golang >Goroutine 中调用的函数的返回值会发生什么情况?

Goroutine 中调用的函数的返回值会发生什么情况?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-06 07:49:14819浏览

What Happens to the Return Values of Functions Called within Goroutines?

从 Goroutines 返回值会发生什么?

当从 Goroutine 调用函数时,返回值通常会丢失,因为 Goroutines 有其自己的隔离执行环境。虽然函数可以将其返回值存储在堆栈上,但该堆栈与主程序的堆栈是分开的,并且当 goroutine 退出时会被销毁。

函数返回值分析

使用 -gcflags -S 标志检查 getNumber 函数的汇编输出表明它确实将其返回值存储在stack:

"".getNumber t=1 size=16 value=0 args=0x10 locals=0x0
    0x0000 00000 (z.go:5)   TEXT    "".getNumber+0(SB),4,<pre class="brush:php;toolbar:false">func getNumber(i int) int {
    return i
}

func main() {
    for i := 0; i < 10; i++ {
        go printNumber(i)
    }
    time.Sleep(5)
}
-16 0x0000 00000 (z.go:6) MOVQ "".i+8(FP),BX 0x0005 00005 (z.go:6) MOVQ BX,"".~r1+16(FP) 0x000a 00010 (z.go:6) RET

但是,该值存储在 Goroutine 内的新堆栈上,该堆栈随后在 Goroutine 终止时被销毁,从而导致主程序无法访问返回值。

示例

考虑以下内容code:

func getNumber(i int) chan int {
    ch := make(chan int)
    go func() {
        ch <- i
    }()
    return ch
}

func main() {
    for i := 0; i < 10; i++ {
        ch := getNumber(i)
        num := <-ch
        fmt.Println(num)
    }
    time.Sleep(5)
}

在这个例子中,getNumber函数被作为goroutine调用,它的返回值并不能立即使用,因为它存储在单独的堆栈上。

应该我们在 Goroutine 中避免返回值吗?

为了避免丢失返回值,一般建议使用通信方式Goroutine 和主程序之间共享数据的通道等机制:

以上是Goroutine 中调用的函数的返回值会发生什么情况?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn