需要了解 goroutines

Need understanding of goroutines

刚接触Go语言编程,一步步学习
在实践中,我发现了 goroutines 的随机行为。
如果我调用 goroutine(睡眠时间为 1 秒的函数),有时它会成功完成,有时却不会:

package main

import (
    "fmt"
    "time"
)

func t(i int) {
    fmt.Println("In func t")
    time.Sleep(1)
}

func t1(i int) {
    fmt.Println("In func t1")
    time.Sleep(1)
}

func main() {
    fmt.Println("Hello Good Morning")
    go t(1)
    t1(2)
    time.Sleep(5)
    fmt.Println("End of func main")
}

O/p 1 :

  Hello Good Morning
  In func t1
  In func t
  End of func main

O/p 2 :

  Hello Good Morning
  In func t1
  End of func main

有人可以解释为什么 goroutine 不保证 goroutine 函数调用的执行。

两件事:

  1. 如果您 return 从 main 没有明确等待您的 goroutine 完成,不能保证它会在之前完成 程序退出。
  2. time.Sleep()的参数类型为time.Duration, 其单位是纳秒。因为你几乎没有延迟 总之,你的结果是随机的也就不足为奇了。如果你睡觉 在 main 的更大量时间里,您应该会看到两者 打印行数(虽然不能保证)。

如果您需要等待 goroutine 完成,有多种方法可以做到这一点(例如,通道和 sync.WaitGroup)。

您可能想要通过 A Tour of Go and/or take a look at Effective Go

Program execution:

When the function main returns, the program exits. It does not wait for other (non-main) goroutines to complete.

1- main 也是goroutine,需要等待其他goroutine完成,可以使用

time.Sleep(5 * time.Second)

等待 5 秒,尝试 The Go Playground:

package main

import (
    "fmt"
    "time"
)

func t(i int) {
    fmt.Println("In func t")
    time.Sleep(1 * time.Second)
}

func t1(i int) {
    fmt.Println("In func t1")
    time.Sleep(1 * time.Second)
}

func main() {
    fmt.Println("Hello Good Morning")
    go t(1)
    t1(2)
    time.Sleep(5 * time.Second)
    fmt.Println("End of func main")
}

输出:

Hello Good Morning
In func t1
In func t
End of func main

并查看文档:

// Sleep pauses the current goroutine for at least the duration d.
// A negative or zero duration causes Sleep to return immediately.
func Sleep(d Duration)

2- 你可以使用 sync.WaitGroup 来等待其他 goroutines,在 The Go Playground:

上试试
package main

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

var w sync.WaitGroup

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

func main() {
    w.Add(1)
    go say("A")

    w.Add(1)
    say("B")

    w.Wait()
}

输出:

B
A
A
B