go - goroutine 没有输出

标签 go concurrency goroutine

SayHello() 按预期执行时,goroutine 什么也不打印。

package main

import "fmt"

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

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

最佳答案

当你的 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.

this answer了解更多详情。

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

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
}

另一种选择是通过关闭 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() 函数随机打印“混合”数字:您无法保证观察到这种行为。再次,参见 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

关于go - goroutine 没有输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28958192/

相关文章:

parallel-processing - 数据通道关闭时 Goroutines 不退出

java - 线程完成后显示共享计数器

Mongodb 对例程的查询会产生巨大的堆栈跟踪

multithreading - 从 goroutine func 发出修改映射

go - 所有 goroutines 都处于休眠状态

go - 无法调用Go-gin中间件

go - 为什么 go get -u 在模块目录中需要很长时间,但在 golang 中却很快完成?

go - go语法struct {} {}的含义是什么

multithreading - 使用汇总的Scala并行频率计算不起作用

java - 在 Java 中执行 ActionPerformed 期间更新 JTextFields