在Go中使用地图时忽略goroutine /线程安全的危险是什么?

时间:2016-02-16 11:17:04

标签: multithreading go thread-safety

Go map据称不是goroutine-safe(请参阅herehere)。我很想知道在我忽略使用互斥锁等保护对地图的访问的情况下会发生什么。

具体,可以发生以下任何情况吗?

  1. 假设我有一个包含密钥k1k2,...,kn的地图,当我要求{{{}时,并发问题会导致获得map[ki] 1}}(i!= j)?
  2. 它可以导致应用程序中的map[kj]吗?

1 个答案:

答案 0 :(得分:3)

正如评论已经说过,比赛很糟糕。与Java不同,Go具有非常弱的保证,因此即使在不执行包含竞赛的代码时,也允许具有任何种族的程序具有未定义的行为。在C中,这被称为“catch-fire语义”。种族的存在意味着任何结果都是可能的,包括你的计算机着火。

然而,在Go中,很容易使地图成为线程安全的。请考虑以下事项:

// Global variable defining a map
var safemap = struct {
    sync.RWMutex
    m map[string]string
}{m: make(map[string]string)}

你可以像这样从地图上安全地读取:

// Get a read lock, then read from the map
safemap.RLock()
defer safemap.RUnlock()
return safemap.m[mykey] == myval

你可以做这样的安全修改:

// Delete from the map
safemap.Lock()
delete(safemap.m, mykey)
safemap.Unlock()

或者这个:

// Insert into the map
safemap.Lock()
safemap.m[mykey] = myval
safemap.Unlock()