About go memory model wrong example

99 views
Skip to first unread message

林风

unread,
Oct 29, 2019, 8:54:38 AM10/29/19
to golang-nuts
在此输入代码...// this works
package main

import (
"sync"
"sync/atomic"
"time"
)

var a int32
var done int32
var once sync.Once

func setup() {
a = 22222
// write
atomic.StoreInt32(&done, 1)
}

func doprint() {
if done == 0 { // if we use atomic to get value here, it's all fine. but why? read a bool variable should be atomic
once.Do(setup)
}
// read
println("get", a)
}

func twoprint() {
go doprint()
go doprint()
}

func main() {
twoprint()
time.Sleep(time.Hour)
}

i do a little change on
https://golang.org/ref/mem incorrect useage synchronization session.
it really bother me why this code have data race, i see this kind of code in runtime.channel, it also just use channel.closed without lock. 

Ian Lance Taylor

unread,
Oct 29, 2019, 10:19:47 AM10/29/19
to 林风, golang-nuts
In these kinds of discussions the word "atomic" has several different
meanings, and it's important to keep them clear. When you say that
reading a bool variable is atomic, you probably mean that the memory
load cannot be mixed with any other memory read or write. That is
true. But there is another important point there, which is when a
memory write M done by processor A can be seen by processor B, and
what that implies, if anything, about when processor B will see other
writes done by processor A before or after M. In the code above, it
is possible that B will see the write to "done" before it sees the
write to "a", even though A does them in the order. You need to use
atomic instructions to avoid seeing the unexpected write ordering.

The runtime support for channels has a comment explaining why the
memory ordering doesn't matter in that particular case.

Ian
Reply all
Reply to author
Forward
0 new messages