将一个地图分配给另一个地图在golang中安全吗?

G.y*_*ang -1 go

代码如下:

    m := make(map[interface{}]interface{})
    //read
    for i := 0; i< 10000; i++ {
        go func() {
            for range m {

            }
        }()
    }
    //write
    for i := 0; i< 10000; i++ {
        go func() {
            mTemp := make(map[interface{}]interface{})
            m = mTemp
        }()
    }
Run Code Online (Sandbox Code Playgroud)

有10000个读goroutine访问m,另外10000个写goroutine为m分配一个新的map,安全吗?

icz*_*cza 5

您有 goroutines 读取m变量,并且 goroutines 写入m变量而无需显式同步。这是一场数据竞争,因此是未定义的行为。

在启用竞争检测器的情况下运行它:

$ go run -race play.go
==================
WARNING: DATA RACE
Write at 0x00c00008c000 by goroutine 15:
  main.main.func2()
      /home/icza/gows/src/play/play.go:17 +0x46

Previous read at 0x00c00008c000 by goroutine 5:
  main.main.func1()
      /home/icza/gows/src/play/play.go:8 +0x45

Goroutine 15 (running) created at:
  main.main()
      /home/icza/gows/src/play/play.go:15 +0xdd

Goroutine 5 (finished) created at:
  main.main()
      /home/icza/gows/src/play/play.go:7 +0xa4
==================
Found 1 data race(s)
exit status 66
Run Code Online (Sandbox Code Playgroud)

查看相关问题:

在没有锁的情况下并发读取函数指针是否安全?

还有一个通过故意数据竞争破坏 Go 内存安全的示例:Golang data races to Break memory safety

  • @G.yang 行为未定义。如果“有时”它对你有用,那么也属于“不防卫”行为。在其他时间或在其他平台上它可能会崩溃。不要玩魔鬼,只需使用适当的同步即可。 (2认同)
  • @G.yang 地图是否是引擎盖下的指针并不重要。读取地图指针并更改它对于竞争条件也不例外。阅读链接的问题/文章了解详细信息/示例。 (2认同)