本文介绍了在Go中使用地图时忽略goroutine /线程安全的危险是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Go的 map 被说成不是 goroutine-safe (参见和)。我很想知道在我忽略使用互斥体/等保护对地图的访问的情况下会发生什么。



特别 ,可以发生以下任何事情吗?


  1. 假设我有一个带有键 k1 , k2 ,..., kn ,并发问题会导致获得 map [ki] 当我要求 map [kj] (i!= j)?
  2. 它可以导致应用程序中的恐慌吗?


解决方案

正如评论已经指出的那样,比赛很糟糕。与Java不同,Go具有非常弱的保证,因此即使含有种族的代码没有执行,也允许任何种族的程序具有未定义的行为。在C中,这被称为catch-fire语义。比赛的出现意味着任何结果都是可能的,包括你的电脑着火。



然而,在Go中很容易使线图安全。考虑以下几点:

  //全局变量定义映射
var safemap = struct {
sync。 RWMutex
m map [string] string
} {m:make(map [string] string)}

您可以像这样从映射中进行安全读取:

  //获取读取锁定,然后读取从地图
safemap.RLock()
defer safemap.RUnlock()
返回safemap.m [mykey] == myval

您可以进行如下安全修改:

  //从地图删除
safemap.Lock()
delete(safemap.m,mykey)
safemap.Unlock()

或者:

  //插入地图
safemap.Lock()
safemap.m [mykey] = myval
safemap.Unlock()


Go's map is said not to be goroutine-safe (see here and here). I'm interested at finding out what could happen in a case where I neglect to protect access to the map using mutex/etc.

Specifically, can any of the following happen?

  1. Assuming I have a map with keys k1, k2, ..., kn, can a concurrency issue lead to getting map[ki] when I asked for map[kj] (i != j)?
  2. Can it lead to a panic in the application?
解决方案

As the comments have already stated, races are bad. Go has very weak guarantees, unlike Java, and hence a program that has any race is allowed to have undefined behavior even when the race-containing code is not executed. In C, this is called "catch-fire semantics". The presence of a race means any outcome is possible, to include your computer catching on fire.

However, in Go it is easy to make a map thread-safe. Consider the following:

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

You can do safe reads from the map like this:

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

And you can do safe modifications like this:

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

or this:

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

这篇关于在Go中使用地图时忽略goroutine /线程安全的危险是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 23:18