3

这个例子取自tour.golang.org/#63

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
}

输出

hello
world
hello
world
hello
world
hello
world
hello

为什么world只打印4times 而不是5?


编辑:可以从golang规范中引用答案:

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

4

3 回答 3

5

当你的 main 函数结束时,你的程序结束,即所有的 goroutine 都被终止。您的 main 在go say("world")完成之前终止。如果你在 main 结束时睡了一段时间,你应该会看到最后一个世界。

于 2013-09-03T19:32:32.927 回答
4

以下是正确解决同步问题的方法 - 使用sync.WaitGroup

游乐场链接

package main

import (
    "fmt"
    "sync"
    "time"
)

func say(s string, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    wg := new(sync.WaitGroup)
    wg.Add(2)
    go say("world", wg)
    go say("hello", wg)
    wg.Wait()
    fmt.Println("All done")
}
于 2013-09-03T20:54:10.423 回答
2

因为调用 gorouting 在您生成的第二个之前终止。这会导致第二个关闭。为了说明,稍微修改您的代码:

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Print(i)
        fmt.Println(":"+s)
    }
}

func main() {
    go say("world")
    say("hello")
}

尝试在 main 函数的末尾放置“等待”或睡眠。

于 2013-09-03T19:35:56.827 回答