我试图更全面地了解channel等共享状态之间的Happens-Before关系的性质。具体而言,我想看看在channel创建某种记忆围栏发送和接收操作。
例如,如果我的信道上发送一个消息,执行周边共享状态"happen before"的send/receive操作的变形例的所有其它操作。在我的特殊例子中,我永远只从单一的常规去写,然后从一个单一的常规去阅读。
(旁白:在下面的例子中,答案显然是把直接的channel的Person
结构的实例,但是这不是我在问什么。)
package main
func main() {
channel := make(chan int, 128)
go func() {
person := &sharedState[0]
person.Name = "Hello, World!"
channel <- 0
}()
index := <-channel
person := sharedState[index]
if person.Name != "Hello, World!" {
// unintended race condition
}
}
type Person struct{ Name string }
var sharedState = make([]Person, 1024)
分析解答
存储模式保证了channel写操作执行时,在channel操作之前出现的是够程的所有操作都是可见的。因此,在您的例子中,"unintended race condition"不可能发生,因为当读取channel,分配在够程发生的事情是可见的。这当然,假定存在不是唯一的写入同一个变量另一个够程。如果有其他的goroutine写入同一个变量,那么你就需要给够程同步,以及避免了比赛。