当您的main() 函数结束时,您的程序也会结束。它不会等待其他 goroutine 完成。
引用Go Language Specification: Program Execution:
程序执行从初始化主包开始,然后调用函数main。当该函数调用返回时,程序退出。它不会等待其他(非main)goroutine 完成。
更多详情请见this answer。
您必须告诉您的 main() 函数等待作为 goroutine 启动的 SayHello() 函数完成。您可以将它们与频道同步,例如:
func SayHello(done chan int) {
for i := 0; i < 10; i++ {
fmt.Print(i, " ")
}
if done != nil {
done <- 0 // Signal that we're done
}
}
func main() {
SayHello(nil) // Passing nil: we don't want notification here
done := make(chan int)
go SayHello(done)
<-done // Wait until done signal arrives
}
另一种选择是通过关闭通道来表示完成:
func SayHello(done chan struct{}) {
for i := 0; i < 10; i++ {
fmt.Print(i, " ")
}
if done != nil {
close(done) // Signal that we're done
}
}
func main() {
SayHello(nil) // Passing nil: we don't want notification here
done := make(chan struct{})
go SayHello(done)
<-done // A receive from a closed channel returns the zero value immediately
}
注意事项:
根据您的编辑/cmets:如果您希望 2 个正在运行的 SayHello() 函数随机打印“混合”数字:您无法保证观察到这种行为。同样,请参阅aforementioned answer 了解更多详细信息。 Go Memory Model 只保证某些事件在其他事件之前发生,你无法保证 2 个并发 goroutines 是如何执行的。
您可能会尝试使用它,但要知道结果不会是确定性的。首先,您必须启用多个活动的 goroutine 来执行:
runtime.GOMAXPROCS(2)
其次,您必须首先将 SayHello() 作为 goroutine 启动,因为您当前的代码首先在主 goroutine 中执行 SayHello(),并且只有在它完成后才会启动另一个:
runtime.GOMAXPROCS(2)
done := make(chan struct{})
go SayHello(done) // FIRST START goroutine
SayHello(nil) // And then call SayHello() in the main goroutine
<-done // Wait for completion