goroutine 没有输出

当SayHello()按预期执行时,goroutine 不打印任何内容。


package main


import "fmt"


func SayHello() {

    for i := 0; i < 10 ; i++ {

        fmt.Print(i, " ")

    }

}


func main() {

    SayHello()

    go SayHello()

}


慕标琳琳
浏览 378回答 3
3回答

慕标5832272

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

肥皂起泡泡

或者(对于 icza 的回答)您可以使用WaitGroupfromsync包和匿名函数来避免更改原始SayHello.package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync")func SayHello() {&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Print(i, " ")&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; SayHello()&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; SayHello()&nbsp; &nbsp; }()&nbsp; &nbsp; wg.Wait()}为了同时打印数字,在单独的例程中运行每个打印语句,如下所示package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "math/rand"&nbsp; &nbsp; "sync"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go func(fnScopeI int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // next two strings are here just to show routines work simultaneously&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amt := time.Duration(rand.Intn(250))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(time.Millisecond * amt)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Print(fnScopeI, " ")&nbsp; &nbsp; &nbsp; &nbsp; }(i)&nbsp; &nbsp; }&nbsp; &nbsp; wg.Wait()}

MM们

当main函数返回时,Go 程序退出。一种选择是使用类似的方法sync.WaitGroup来等待main从main.另一种方法是调用runtime.Goexit()在main。从godoc:Goexit 终止调用它的 goroutine。没有其他 goroutine 受到影响。Goexit 在终止 goroutine 之前运行所有延迟调用。因为 Goexit 不是一个恐慌,这些延迟函数中的任何恢复调用都将返回 nil。从主协程调用 Goexit 会终止该协程,而不会返回 func main。由于 func main 没有返回,程序继续执行其他 goroutine。如果所有其他 goroutine 退出,程序就会崩溃。这允许 main goroutine 停止执行,而后台例程继续执行。例如:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "runtime"&nbsp; &nbsp; "time")func f() {&nbsp; &nbsp; for i := 0; ; i++ {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(i)&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(10 * time.Millisecond)&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; go f()&nbsp; &nbsp; runtime.Goexit()}这比在 main 函数中永远阻塞更干净,尤其是对于无限的程序。一个缺点是,如果进程的所有 goroutine 都返回或退出(包括主 goroutine),Go 会将其检测为错误和恐慌:fatal error: no goroutines (main called runtime.Goexit) - deadlock!为了避免这种情况,至少一个 goroutine 必须os.Exit在它返回之前调用。调用os.Exit(0)立即终止程序并指示它没有错误地这样做。例如:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "os"&nbsp; &nbsp; "runtime"&nbsp; &nbsp; "time")func f() {&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(i)&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(10 * time.Millisecond)&nbsp; &nbsp; }&nbsp; &nbsp; os.Exit(0)}func main() {&nbsp; &nbsp; go f()&nbsp; &nbsp; runtime.Goexit()}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go