且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

goroutine 没有输出

更新时间:2022-11-30 16:43:48

当您的 main() 函数结束时,您的程序也会结束.它不会等待其他 goroutine 完成.

When your main() function ends, your program ends as well. It does not wait for other goroutines to finish.

引自 Go 语言规范:程序执行:

程序执行首先初始化主包,然后调用函数main.当该函数调用返回时,程序退出.它不会等待其他(非main)goroutines 完成.

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.

有关详细信息,请参阅此答案.

See this answer for more details.

您必须告诉您的 main() 函数等待作为 goroutine 启动的 SayHello() 函数完成.您可以将它们与频道同步,例如:

You have to tell your main() function to wait for the SayHello() function started as a goroutine to complete. You can synchronize them with channels for example:

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
}

另一种选择是通过关闭通道来表示完成:

Another alternative is to signal the completion by closing the channel:

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
}

注意事项:

根据您的编辑/评论:如果您希望 2 个正在运行的 SayHello() 函数随机打印混合"数字:您不能保证观察到这种行为.同样,请参阅上述答案了解更多详情.Go Memory Model 只保证某些事件发生在其他事件之前,你有不保证 2 个并发 goroutine 是如何执行的.

According to your edits/comments: if you want the 2 running SayHello() functions to print "mixed" numbers randomly: you have no guarantee to observe such behaviour. Again, see the aforementioned answer for more details. The Go Memory Model only guarantees that certain events happen before other events, you have no guarantee how 2 concurrent goroutines are executed.

您可以试验它,但要知道结果不是确定性的.首先,您必须启用多个活动 goroutines 才能执行:

You might experiment with it, but know that the result will not be deterministic. First you have to enable multiple active goroutines to be executed with:

runtime.GOMAXPROCS(2)

其次你必须首先将 SayHello() 作为 goroutine 启动,因为你当前的代码首先在主 goroutine 中执行 SayHello() 并且只有在它完成后才会启动另一个:

And second you have to first start SayHello() as a goroutine because your current code first executes SayHello() in the main goroutine and only once it finished starts the other one:

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