- 对一个元素的send操作Happens Before对应的receive 完成操作
- 对channel的close操作Happens Before receive 端的收到关闭通知操作
- 对于Unbuffered Channel,对一个元素的receive 操作Happens Before对应的send完成操作
- 对于Buffered Channel,假设Channel 的buffer 大小为C,那么对第k个元素的receive操作,Happens Before第k+C个send完成操作。 可以看出上一条Unbuffered Channel规则就是这条规则C=0时的特例 注意:对于Buffered Channel不能保证一个元素的receive操作Happens Before对应的send完成操作
Happens Before receive/send完成操作指在receive/send下一条操作之前完成。不是指在receive/send之前完成。如下面的例子:执行到<-c语句并不代表receive完成,而执行到print(a)则可保证receive已经完成。
var c = make(chan int, 10)
var a string
func f() {
a = "hello, world"
c <- 0
}
func main() {
go f()
<-c
print(a)
}
保证输出hello,world。原因 c<-0(send操作) happedns before print(a)(receive完成操作) 对a的写入必定在c<-0的前面。打印a必定在<-c的后面。所以保证输出hello,world。
// Channel routine 2
var c = make(chan int, 10)
var a string
func f() {
a = "hello, world"
<-c
}
func main() {
go f()
c <- 0
print(a)
}
由于Buffered Channel不能保证一个元素的receive操作Happens Before对应的send完成操作,因此不能保证<-c(receive操作) Happens Before print(a)(send完成操作),即不能保证对a的写入在print(a)的前面。所以可能会打印empty string
// Channel routine 1
var c = make(chan int)
var a string
func f() {
a = "hello, world"
<-c
}
func main() {
go f()
c <- 0
print(a)
}
<- c(receive操作) happens before print(a)(send完成操作),所以可以保证打印hello,world。