如果我错了,请纠正我。只要我知道,goroutine的工作方式大致类似于线程。所以如果我用不同的参数生成相同的函数,前缀为go。它应该工作得很好吗?
package main
import "fmt"
func f(from string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
}
func main() {
go f("direct")
go f("redirect")
//var input string
//fmt.Scanln(&input)
}
实际输出:
rahul@g3ck0:~/programs/go$ go run goroutine.go
rahul@g3ck0:~/programs/go$
我刚回来提示。
预期产出:
direct : 0
direct : 1
direct : 2
redirect : 0
redirect : 1
redirect : 2
不一定是相同的顺序 无法理解这种奇怪的行为。我错过了什么吗?
编辑:添加扫描语句会解决它。但有没有更好的方法呢?
答案 0 :(得分:6)
当主要退出时,无论其他goroutines的状态如何,程序都会终止。您可以通过在主函数末尾添加select{}
来测试此项。这将导致main永远不会退出,您将看到其他goroutines运行。
如果你希望你的程序在两个goroutine完成时干净地退出(没有死锁),你需要使用类似通道或sync.Waitgroup的东西来协调一切都完成时的主要结局。
使用sync.Waitgroup的示例:
package main
import (
"fmt"
"sync"
)
func f(from string, wg *sync.WaitGroup) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
wg.Done()
}
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go f("direct", wg)
go f("redirect", wg)
wg.Wait()
}
使用频道的示例:
package main
import (
"fmt"
)
func f(from string, ch chan<- bool) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
ch <- true
}
func main() {
ch := make(chan bool)
go f("direct", ch)
go f("redirect", ch)
<-ch
<-ch
}
答案 1 :(得分:0)
如上所述,最后的select {}确保显示输出,但您不能指望go例程以特殊顺序运行。
如果您运行parallell go例程,则无法保证它们将以何种顺序运行。除了它们之外,你不能按顺序运行,因为它们是并行运行的!
您可能会在一台机器上获得预期的输出时间,但不能保证每次在任何给定的机器上打印输出都是有序的!!