gpt4 book ai didi

如果包含 time.Sleep,Goroutine 不会执行

转载 作者:IT老高 更新时间:2023-10-28 13:10:26 28 4
gpt4 key购买 nike

以下代码运行良好:

package main

import (
"fmt"
)

func my_func(c chan int){
fmt.Println(<-c)
}

func main(){
c := make(chan int)
go my_func(c)

c<-3
}

playgound_1

如果我改变了

c<-3

time.Sleep(time.Second)
c<-3

playground_2

我的代码没有执行。

我的直觉是 mainmy_func 完成执行之前返回,但似乎添加暂停应该没有任何效果。我完全迷失在这个简单的例子中,这是怎么回事?

最佳答案

main函数结束,程序以它结束。它不会等待其他 goroutine 完成。

引自 Go Language Specification: Program Execution :

Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.

当您的main函数通过在 channel 上发送值成功,程序可能会立即终止,在另一个 goroutine 有机会将接收到的值打印到控制台之前。

如果您想确保将值打印到控制台,您必须将其与退出 main 的事件同步。功能:

以“完成” channel 为例(在 Go Playground 上试用):

func my_func(c, done chan int) {
fmt.Println(<-c)
done <- 1
}

func main() {
c := make(chan int)
done := make(chan int)
go my_func(c, done)

time.Sleep(time.Second)
c <- 3
<-done
}

自从 done也是一个无缓冲 channel ,在 main 结束时从它接收函数必须等待 done 上的值的发送 channel ,发生在 channel c 上发送的值之后已收到并打印到控制台。

对看似不确定的运行的解释:

Goroutines 可能会或可能不会并行执行同时。同步确保某些事件在其他事件之前发生。这是您获得的唯一保证,也是您唯一应该依赖的东西。2 个例子发生在之前:

  • The go statement that starts a new goroutine happens before the goroutine's execution begins.
  • A send on a channel happens before the corresponding receive from that channel completes.

更多详情请阅读 The Go Memory Model .

回到你的例子:

A receive from an unbuffered channel happens before the send on that channel completes.

所以你得到的唯一保证是运行 my_func() 的 goroutine将从 channel c 接收值发自 main() .但是一旦收到值,main函数可能继续,但由于发送后没有更多的语句,它只是结束 - 与程序一起。是否非main goroutine 将有 时间机会 使用 fmt.Println() 打印它没有定义

关于如果包含 time.Sleep,Goroutine 不会执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28307783/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com