疑问 没有缓存的chan在发送阻塞的时候已经把值存进去了还是在读的时候存的

a312024054 · · 2394 次点击
规范里面对Send statements的说明是: Both the channel and the value expression are evaluated before communication begins 问题的关键在于communication begins发生在什么时候? 这里有4个时间点: A:num++ B1:<-c begin B2: <-c return C1: c <- *p begin C2: c <- *p return D: *p这个表达式求值 根据Go memory model,有几个happen before是可以确定的: C1在B2之前,B2在C2之前, A在B1之前,B1在B2之前 C1--------B2-----C2 | A---B1---- communication begins的时间点应该是B1与B2之间,并且同时也是C1与C2之间,按上图就是:max(B1, C1)到B2之间的一个时间点,假设为X 就是说D发生在goroutine里面time.Sleep(time.Second)之后,X之前 那么就有下面两种情况: 如果B1>C1(C1发生在B1之前),那么X在B1与B2之间,A一定在X之前,但是D也在X之前,A和D的顺序不能确定 如果C1>B1(B1发生在C1之前),那么X在C1与B2之间,A一定在X之前,但是D也在X之前,A和D的顺序不能确定
#26
更多评论
你这个有 data race,结果具有不确定性
#1
<a href="/user/channel" title="@channel">@channel</a> 所以两个的睡眠时间是不一样的呀
#2