我正在浏览 Go Bootcamp,现在正在阅读 Go 并发章节。我以前从未在编程中使用过并发,也不理解这个程序的输出:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 2; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
输出:
hello
world
hello
Program exited.
有人能解释一下为什么“world”不像“hello”那样打印两次吗?也许阐明使用并发的想法?
注意,Go Playground 链接 here .
Go 程序在 main 返回时退出。在这种情况下,您的程序在退出之前不会等待最终的“世界”在另一个 goroutine 中打印出来。
以下代码 ( playground ) 将确保 main 永远不会退出,从而允许其他 goroutine 完成。
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 2; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
select{}
}
您可能已经注意到,这会导致死锁,因为程序无法继续前进。您可能希望添加一个 channel 或一个 sync.Waitgroup 以确保程序在另一个 goroutine 完成后立即干净地退出。
例如 ( playground ):
func say(s string, ch chan<- bool) {
for i := 0; i < 2; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
if ch != nil {
close(ch)
}
}
func main() {
ch := make(chan bool)
go say("world", ch)
say("hello", nil)
// wait for a signal that the other goroutine is done
<-ch
}