On Sat, Oct 28, 2017 at 12:58 AM, T L <tapir....@gmail.com> wrote: > Aha, if the second gorotuine "go func() { close(ch) }()" is removed from > your example, > then I can't find any flaw in what your said. > The two new created goroutines in your example really builds a > relationship as described in the Go 1 memory model article. > The relationship guarantees "a, b = 0, 1" will never happen. >
No. My program has the following (relevant) events: A: go func() {…} B: x = 1 C: <-ch D: y = 1 E: go func() {…} F: close(ch) G: a = x H: b = y Now, let's look at happens-before relationships: Within a single goroutine, the happens-before order is the order expressed > by the program. B ≤ C ≤ D A ≤ E ≤ G ≤ H Goroutine creation A ≤ B, C, D E ≤ F Channel communication F ≤ C This enumerates the partial order guaranteed: As should be immediately obvious, that B/D and G/H happen concurrently (as defined by the memory model); there is no ordered path from one to the other (in either direction). Now, looking at the memory model to see what G/H are thus allowed to observe. We need to answer two questions to see whether we can observe a,b=0,1: a) is H allowed to observe D? and b) is G guaranteed to observe C? If a) is answered with "yes" and b) is answered with "no", then a,b=0,1 is valid. A read r of a variable v is allowed to observe a write w to v if both of > the following hold: > * r does not happen before w. > * There is no other write w' to v that happens after w but before r. H does not happen before D. There is no other write to y (and the only other write in general also does not happen before H). So both of these conditions are true, the answer to a) is "yes". […] r is guaranteed to observe w if both of the following hold: > * w happens before r. > * Any other write to the shared variable v either happens before w or > after r. C does not happen before G, so the first condition is violated. Thus, G is not guaranteed to observe C, the answer to b) is "no". Thus, the memory model allows a,b=0,1. I hope this discussion illustrates, why it's important to talk about multiple goroutines and observability. It certainly helped me understand the memory model better :) Lastly, there is this relevant quote from the page: If you must read the rest of this document to understand the behavior of > your program, you are being too clever. Best, Axel > > On Friday, October 27, 2017 at 4:50:18 PM UTC-4, Axel Wagner wrote: >> >> I'm not an expert, but I think this is an invalid oversimplification. Say >> you have three goroutines: >> >> var x, y int >> ch := make chan int >> go func() { >> x = 1 >> <-ch >> y = 1 >> }() >> go func() { >> close(ch) >> }() >> a, b := x, y >> >> From my understanding of the memory model, it would be legal to get a, b >> = 0, 1 (thus, the write of y was observed before the write of x). >> The reason is, that the memory model only makes guarantees for the >> ordering of effects of goroutine A observed by goroutine B, if there is a >> happens-before edge *between these two goroutines*. The assignments to a >> resp. b have no happens-before edges with the assignments of x or y. >> >> So, any formulation of the memory-model guarantees necessarily have to >> talk about relationships between multiple goroutines and their statements. >> >> But I'm not an expert. I consider all of this memory-model, >> happens-before-relationship arguing to be incredibly tedious. Which is why >> I just a) add synchronization points when I need to concurrently access >> data, b) just in general rather lock too much than too little and c) hope >> that the race detector can tell me when I'm wrong. Rules-lawyering, it >> would seem to me, is not a terribly promising strategy. >> >> >> On Fri, Oct 27, 2017 at 10:39 PM, T L <tapi...@gmail.com> wrote: >> >>> Go 1 memory model guarantee that the relative order of the two >>> statements will not get exchanged, >>> if there is one any of the following operation between the two >>> statements in code: >>> * a channel read >>> * a channel write >>> * a channel close >>> * a sync.Mutex.Lock() >>> * a sync.Mutex.Unlock() >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "golang-nuts" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to golang-nuts...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.