并发访问无锁变量

I was disturbed by a question,

should we add lock if only one thread write variable, and other thread just read variable?

so I write such code to test it

package main

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

var lock sync.RWMutex
var i = 0

func main() {
    runtime.GOMAXPROCS(2)
    go func() {
        for {
            fmt.Println("i am here", i)
            time.Sleep(time.Second)
        }
    }()
    for {
        i += 1
    }
}

The result is keep print i am here 0 even after second of time. I know a little about Memory barrier or cpu cache. but how could it be cache for such a long time? I think after a few time, it should read variable I already changed.

Can anyone who is master go or computer system could help answer, please?


Update: i know it is a wrong way to update variable like this, i want to know why it is undefined in cpu/memory view.

finally, i find this answers, i know with a data race you will get a undefined behave, but i want to know why it behave like that currently.

this snap code is because complier just remove Add function, it never add.

so we have lesson, if you write a undefined behave, you may got a moon - -

complier will treat you code as rubbish, it does not have any value.

should we add lock if only one thread write variable, and other thread just read variable?

Yes. Always. No arguing here.

Your test code proves and disproves nothing as its behaviour is undefined.

You have a data race. Therefore, the results are undefined.

package main

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

var lock sync.RWMutex
var i = 0

func main() {
    runtime.GOMAXPROCS(2)
    go func() {
        for {
            fmt.Println("i am here", i)
            time.Sleep(time.Second)
        }
    }()
    for {
        i += 1
    }
}

Output:

$ go run -race racer.go
==================
WARNING: DATA RACE
Read at 0x0000005e3600 by goroutine 6:
  main.main.func1()
      /home/peter/gopath/src/racer.go:17 +0x63

Previous write at 0x0000005e3600 by main goroutine:
  main.main()
      /home/peter/gopath/src/racer.go:22 +0x7b

Goroutine 6 (running) created at:
  main.main()
      /home/peter/gopath/src/racer.go:15 +0x4f
==================
i am here 3622
i am here 43165250
i am here 86147697
^Csignal: interrupt
$

References:

Data Race Detector

Benign Data Races: What Could Possibly Go Wrong?