(you’re comments were quoted, but I think I am replying correctly).

The memory barriers provided by the Write Lock, and release will force the 
flush to memory of all mutations before the flush (the closed mutation) - 
meaning the atomic read will read the correct value.

There is a chance that a fully specified memory model could make that not be 
possible, but in the current de-facto memory model it is going to be the case 
on any CPU architecture I’m aware of. Some transactional memory systems might 
be able to avoid the flush on the ‘closed’, but unlikely.

I would welcome you writing a test case to demonstrate this not being the case 
and failing.

The reason the race detector reports a race is because it expects all access to 
be guarded by the same guard, the Lock/Release must perform the same memory 
barriers on the SMP systems I’m aware of.

The comment on the better “read” method is definitely the way to go. It still 
encapsulates the channel(s), and avoids any of the ambiguity of the memory 
model (while probably improving the performance a bit).

Agreed that the encapsulation can cause issues like you describe, but the 
response was originally related to “priority channels”, and I was demonstrating 
a technique (with additional channels behind the struct) that would allow easy 
implementations of priorities. But the code I provided certainly simplifies the 
case of multi writer/readers with indeterministic behavior/shutdown (without 
using panic/recover which is probably the easiest for the simple case).


> On Sep 2, 2019, at 11:16 AM, roger peppe <rogpe...@gmail.com> wrote:
> 
>> Btw, the removing of the GOMAXPROCS causes things to execute serially- which 
>> is fine according to the spec - but it does make demonstrating certain 
>> concurrency structs/problems pretty difficult.
>> Unless something's changed recently, all programs in the playground execute 
>> without parallelism, so setting GOMAXPROCS shouldn't have any effect. The 
>> fact that it does have an affect appears to be a bug. I'd suggest reporting 
>> it as an issue.
>> 
>> As I pointed out in another reply, I am fairly certain the atomic operations 
>> must be valid in these cases due to the happens before relationship of them 
>> and mutexes.
>> In that other reply:
>> 
>> You can simply validate it by run: go run -race main.go for you program: 
>> https://play.golang.org/p/JRSEPU3Uf17 <https://play.golang.org/p/JRSEPU3Uf17>
>> Not true. The race detector does not detect certain cases and can overreport.
>> Firstly, AFAIK there is no implied happens-before relationship between a 
>> non-atomic write to a variable and an atomic read from a variable, because 
>> there is no synchronization event associated with the atomic read.
>> 
>> Secondly, I am aware that the race detector can give false negatives in some 
>> cases, but it should not provide false positives AFAIK. There's only one 
>> such case that I'm aware of, and that's quite a different issue 
>> <https://github.com/golang/go/issues/22132>.
>> 
>> Given that the race detector reports a race in this very clear and simple 
>> case <https://play.golang.org/p/zunlddLN4cy>, ISTM that your program is 
>> wrong.
>> 
>> From https://golang.org/ref/mem <https://golang.org/ref/mem>:
>> 
>> If you must read the rest of this document to understand the behavior of 
>> your program, you are being too clever.
>> 
>> Don't be clever.
>> Also, there's really no point in the atomic read. You could implement the 
>> Read method as follows:
>> 
>> func (c *MultiWriterIntChan) Read() (int, bool) {
>>      x, ok := <-c.ch <http://c.ch/>
>>      return x, ok  
> 
>> }
> 
>> That is, let the close state flow naturally downstream via the channel. That 
>> way it will still work correctly if you start to use a buffered channel, for 
>> example.
>> 
>> I don’t agree that returning the channel is a proper design, it breaks the 
>> encapsulation. Technically mine could use multiple channels behind the 
>> scenes - yours cannot.
>> There's a trade-off here. By encapsulating in a method, you make it harder 
>> to wait for values in combination with other events (you'd need to create a 
>> goroutine to call your Read method and send the result to a channel, adding 
>> buffering, context switch overhead, and more state that needs to be 
>> explicitly shut down). 
> 
> 
> 
> -- 
> 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 
> <mailto:golang-nuts+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAJhgaci57DOYHOk7C%3DjM8B6wenCxYv4JvNn2%3D13OGcd66Yc3EA%40mail.gmail.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/CAJhgaci57DOYHOk7C%3DjM8B6wenCxYv4JvNn2%3D13OGcd66Yc3EA%40mail.gmail.com?utm_medium=email&utm_source=footer>.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/E2A2D5F4-0DD3-416A-93D1-AD768DCBCA32%40ix.netcom.com.

Reply via email to