Go中没有goroutine的输出 [英] No output from goroutine in Go

查看:132
本文介绍了Go中没有goroutine的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然 SayHello()按预期执行,但goroutine不打印任何内容。






$ b func SayHello() {
for i:= 0;我< 10; i ++ {
fmt.Print(i,)
}
}

func main(){
SayHello()
go SayHello()
}


解决方案

code> main()函数结束,你的程序也会结束。它不会等待其他goroutines完成。



引用 Go Language Specification:Program Execution


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

请参阅此答案了解更多详情。

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

  func SayHello(done chan int){
for i:= 0 ;我< 10; i ++ {
fmt.Print(i,)
}
如果完成了!= nil {
完成< - 0 //表明我们已完成

}

func main(){
SayHello(nil)//传递nil:我们不想在这里通知
完成:= make(chan int)
go SayHello(完成)
<-done //等待完成信号到达
}

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

  func SayHello(done chan struct {}){
for i:= 0;我< 10; i ++ {
fmt.Print(i,)
}
if done!= nil {
close(done)//表明我们完成
}
}
$ b func main(){
SayHello(nil)//传递nil:我们不想在这里通知
完成:= make(chan struct {})
go SayHello(完成)
<-done //从一个封闭的频道接收立即返回零值
}

注意: 根据您的编辑/评论:希望2个运行的 SayHello()函数随机打印混合数字:您无法保证观察到这种行为。再次请参阅上述回答以获取更多详细信息。 Go Memory Model 仅保证某些事件发生在其他事件之前,您有不保证2个并发goroutine是如何执行的。



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

  runtime.GOMAXPROCS(2)

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

<$ p $ (b)> 运行时.GOMAXPROCS(2)
完成:= make(chan结构{})
开始SayHello(done)//第一次开始goroutine
SayHello(nil) //然后在主要的例程中调用SayHello()
< -done //等待完成


While SayHello() executes as expected, the goroutine prints nothing.

package main

import "fmt"

func SayHello() {
    for i := 0; i < 10 ; i++ {
        fmt.Print(i, " ")
    }
}

func main() {
    SayHello()
    go SayHello()
}

解决方案

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

Quoting from the 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.

See this answer for more details.

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
}

Notes:

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.

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)

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

这篇关于Go中没有goroutine的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆