Multithreading 在围棋中使用地图时,忽略goroutine/线程安全有什么危险?
Go的Multithreading 在围棋中使用地图时,忽略goroutine/线程安全有什么危险?,multithreading,go,thread-safety,Multithreading,Go,Thread Safety,Go的地图被称为不安全的goroutine(请参阅和)。我感兴趣的是,如果我忽略了使用互斥锁/等保护对地图的访问,那么会发生什么情况 特别是,是否会发生以下情况 假设我有一个带有键k1,k2,…,kn,当我请求map[kj](I!=j)时,并发问题是否会导致获得map[ki] 它是否会导致应用程序出现死机 正如评论已经指出的,种族是不好的。与Java不同,Go具有非常弱的保证,因此具有任何竞争的程序即使在不执行包含代码的竞争时也可以具有未定义的行为。在C语言中,这被称为“着火语义”。比赛的存在意
地图
被称为不安全的goroutine
(请参阅和)。我感兴趣的是,如果我忽略了使用互斥锁/等保护对地图的访问,那么会发生什么情况
特别是,是否会发生以下情况
k1
,k2
,…,kn
,当我请求map[kj]
(I!=j)时,并发问题是否会导致获得map[ki]
李>
正如评论已经指出的,种族是不好的。与Java不同,Go具有非常弱的保证,因此具有任何竞争的程序即使在不执行包含代码的竞争时也可以具有未定义的行为。在C语言中,这被称为“着火语义”。比赛的存在意味着任何结果都是可能的,包括你的电脑着火 然而,在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()
您可以进行如下安全修改:
// 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()
你会破坏记忆。在go 1.6中,它会故意使程序崩溃,以防止检测到不安全行为。地图是否可以安全地同时使用并不重要,在go中没有任何值可以安全地同时读取和写入。实际上,没有必要知道特定问题的答案。你的密码坏了。破碎,不是“破碎,而是以这种特定的方式破碎,在这种情况下是可以的”。刚刚坏了。@JimB谢谢。不用说,我知道这一点,否则我不会链接到上述来源。实际上,我写了这个回购协议来处理这个问题:但是我从来没有能够证明这个问题,这就是为什么我要问上面的问题。任何能回答我问题的代码参考都将不胜感激。即使你找到了问题的答案,这些答案可能在下一个Go版本中,或在另一个平台上,或当使用不同的编译器时已经过时。。。这使得这些信息变得毫无用处。。。也可能是或的复制品。唯一普遍的答案是,就像任何种族条件一样,任何事情都可能发生。特别是对于地图,一旦它被破坏,你就可以从程序内存中的任何地方读写。每当有人有一个“奇怪的运行时错误”,它几乎总是一个数据竞赛。