-1

Lately, I found some code looks like this:

var m map[int]int

func writem() {
    tmpm := make(map[int]int)
    for i := 0; i < 4000000; i++ {
        tmpm[i] = i + 10
    }
    m = tmpm
}

func readm() {
    for k, v := range m {
        _, _ = k, v
    }
}

func main() {
    writem()
    go readm()
    writem()
}

This program runs fine, but I think the writem function body may be reordered by moving m = tmpm before the for loop, because this doesn't change the behavior within this goroutine. And this reordering will cause the concurrent map read and map write problem. As the Go Memory Model says:

compilers and processors may reorder the reads and writes executed within a single goroutine only when the reordering does not change the behavior within that goroutine as defined by the language specification

Any I right, or it is safe to write code like this?

kostix
  • 51,517
  • 14
  • 93
  • 176
lty
  • 108
  • 1
  • 6
  • 3
    That blurb you quoted doesn't apply to your situation, since the reads and writes are _not_ in the same goroutine. So I don't really understand your question. – Jonathan Hall Mar 09 '19 at 10:56

1 Answers1

7

This program runs fine.

No, it doesn't.


The results of the program are undefined. You have a data race on map m.

$ go run -race racer.go
==================
WARNING: DATA RACE
Write at 0x000000510fa0 by main goroutine:
  main.writem()
      /home/peter/gopath/src/racer.go:10 +0xa7
  main.main()
      /home/peter/gopath/src/racer.go:22 +0x4c

Previous read at 0x000000510fa0 by goroutine 13:
  [failed to restore the stack]

Goroutine 13 (finished) created at:
  main.main()
      /home/peter/gopath/src/racer.go:21 +0x47
==================
Found 1 data race(s)
exit status 66
$ 

racer.go:

package main

var m map[int]int

func writem() {
    tmpm := make(map[int]int)
    for i := 0; i < 4000000; i++ {
        tmpm[i] = i + 10
    }
    m = tmpm
}

func readm() {
    for k, v := range m {
        _, _ = k, v
    }
}

func main() {
    writem()
    go readm()
    writem()
}

Playground: https://play.golang.org/p/OcWmK7ioMkD


Reference: Go: Data Race Detector

peterSO
  • 158,998
  • 31
  • 281
  • 276