试图了解goroutines

che*_*web 1 go goroutine

我一直在玩A Tour of Go中的以下代码,但是当我应用一些小的改动时,我不明白发生了什么.原始代码是这样的

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

它产生了这个

world
hello
hello
world
world
hello
hello
world
world
hello
Run Code Online (Sandbox Code Playgroud)

哪个好:五次你好,五次世界.我打电话的时候开始变得奇怪

say("world")
go say("hello")
Run Code Online (Sandbox Code Playgroud)

现在输出就是

world
world
world
world
world
Run Code Online (Sandbox Code Playgroud)

不管你好吗?它有两个goroutines甚至更奇怪

go say("world")
go say("hello")
Run Code Online (Sandbox Code Playgroud)

现在根本没有输出.当我换i < 5i < 2并打电话

go say("world")
say("hello")
Run Code Online (Sandbox Code Playgroud)

我明白了

world
hello
hello
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?

Cer*_*món 5

如果是

 say("world")
 go say("hello")
Run Code Online (Sandbox Code Playgroud)

"世界"调用必须在"hello"goroutine启动之前完成."hello"goroutine没有运行或完成,因为主要返回.

对于

go say("world")
go say("hello")
Run Code Online (Sandbox Code Playgroud)

由于主要回报,goroutines不会运行或完成.

使用sync.WaitGroup防止main在goroutines完成之前退出:

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

func main() {
  var wg sync.WaitGroup
  wg.Add(2)
  go say(&wg, "world")
  go say(&wg, "hello")
  wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)

操场的例子