Go中没有来自goroutine的输出

Din*_*nam 18 concurrency go goroutine

虽然SayHello()按预期执行,但goroutine没有打印任何内容.

package main

import "fmt"

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

func main() {
    SayHello()
    go SayHello()
}
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 34

当您的main()功能结束时,您的程序也会结束.它不等待其他goroutines完成.

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

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

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

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

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
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是通过关闭频道来表示完成:

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
}
Run Code Online (Sandbox Code Playgroud)

笔记:

根据您的编辑/评论:如果您希望2个运行SayHello()函数随机打印"混合"数字:您无法保证观察到此类行为.再次,请参阅上述答案以获取更多详细信息.在转到内存模型只能保证某些事件发生的其他事件之前,你有没有保证2个并发够程是如何执行的.

你可以尝试一下,但要知道结果不是确定性的.首先,您必须启用多个活动goroutine:

runtime.GOMAXPROCS(2)
Run Code Online (Sandbox Code Playgroud)

第二,你必须首先SayHello()作为goroutine 开始,因为你当前的代码首先SayHello()在主goroutine中执行,只有在完成后才启动另一个:

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
Run Code Online (Sandbox Code Playgroud)


Sun*_*que 10

或者(icza的答案),你可以使用WaitGroupsync包和匿名函数,以避免改变原有的SayHello.

package main

import (
    "fmt"
    "sync"
)

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

func main() {
    SayHello()

    var wg sync.WaitGroup
    wg.Add(1)

    go func() {
        defer wg.Done()
        SayHello()
    }()

    wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)

为了同时打印数字,请在单独的例程中运行每个print语句,如下所示

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func(fnScopeI int) {
            defer wg.Done()

            // next two strings are here just to show routines work simultaneously
            amt := time.Duration(rand.Intn(250))
            time.Sleep(time.Millisecond * amt)

            fmt.Print(fnScopeI, " ")
        }(i)
    }

    wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)