Because there is no write barrier - so the changes that Go routine #1 makes may all be local (in a register), and never flushed to memory. Go routine #2 is also free to keep using the last read value from the cache since there is nothing that would force the cache to be refreshed.
The is an important aspect of synchronization methods - they also provide write and read barriers (for most types). atomics provide the write and read barriers without synchronization. This is why the Go designers stress not to “share memory”, and instead use constructs like channels. It can be very difficult to get shared memory “correct”. > On Feb 1, 2019, at 3:58 PM, Michael Ellis <[email protected]> wrote: > > > > On Friday, February 1, 2019 at 11:11:24 AM UTC-5, robert engels wrote: > > for { > if A.a > 100 { > break > } > > > Go routine #2 may never see the value of A.a change and so never exit the > loop. > > I'm confused. I can see how that would fail if the test were A.a == 100 since > Go routine #1 might increment past 100 before #2 , but as written it seems > wrong only if the application logic depends on Go routine #2 exiting the loop > as soon as A.a reaches 100 (as opposed to any time afterward.) > > What am I missing? > > > > -- > 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 [email protected] > <mailto:[email protected]>. > For more options, visit https://groups.google.com/d/optout > <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 [email protected]. For more options, visit https://groups.google.com/d/optout.
