1.通过go run example.go执行,执行输出顺序为啥不是
1
2
send over
receive over
2.贴代码
package main
func main() {
data := make(chan int)
exit := make(chan bool)
go func() {
for v := range data {
println(v)
}
println("receive over")
exit <- true
}()
data <- 1
data <- 2
// data <- 3
close(data)
println("send over")
<-exit
}
3.环境说明:
Go Version:go1.4.2 darwin/amd64
MacBook Pro (Retina, 13-inch, Early 2015)
2.7 GHz Intel Core i5
8 GB 1867 MHz DDR3
你的执行顺序应该是:
由于 channel是的发送和读取都是阻塞操作。
写入1之后,再写入2被阻塞,cpu让出执行go出的协程,打印出1
再次进入for循环读取channel被阻塞,cpu让出,回到主协程写入2成功,close成功,print成功,输出 send over
读取channel exit被阻塞,cpu让出,执行go出协程,打印出2
由于channel 被关闭,for结束,打印出 receive over,写入 exit,阻塞,cpu让出
读取到 exit的值,程序终止
如果你使用 Go1.5以上版本,多执行几次,你会发现顺序都不是固定的:
Go从1.5版本开始,默认采用多核执行,默认是你的CPU核心数,以前版本默认为1.
https://golang.org/doc/go1.5#...
go开启了一个协程,main其实也是一个协程,我们称之为主协程,主协程和go出去的协程都是协程,并没有绝对的执行顺序,他们是并行调度的,在 close(data)之后,可能go出去的协程先执行完了,也可能主协程print完了坐等exit channel返回数据。由于调度是“随机”的,他们在执行时是不能保证顺序的,程序中也不应该依赖他们的执行顺序。