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.

Reply via email to