如有错误请指正。据我所知,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
不一定是同一个顺序。
无法理解这种奇怪的行为。我错过了什么吗?
编辑:添加 Scan 语句可以解决它。但是有更好的方法吗?
最佳答案
当 main 退出时,无论其他 goroutines 的状态如何,程序都会终止。您可以通过在主函数末尾添加 select{}
来测试它。这将导致 main 永远不会退出,您将看到其他 goroutines 运行。
如果你希望你的程序在两个 goroutines 完成时干净地退出(没有死锁),你需要使用类似 channel 或 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()
}
使用 channel 的例子:
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
}
关于go - 奇怪的协程行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17904882/