gpt4 book ai didi

dictionary - map 内容编辑上的 Golang RWMutex

转载 作者:IT王子 更新时间:2023-10-29 02:26:11 26 4
gpt4 key购买 nike

我开始在带有 map 的 Go 项目中使用 RWMutex,因为现在我有多个例程同时运行并进行所有更改为此,我想到了一个疑问。

问题是我知道我们必须在仅读取时使用 RLock 以允许其他例程执行相同的任务,而在写入全 block map 时必须使用 Lock .但是,在编辑 map 中先前创建的元素时我们应该做什么?

例如...假设我有一个map[int]string,我在其中执行Lock,放入"hello " 和然后解锁。如果我想向其中添加 "world" 怎么办?我应该执行 Lock 还是可以执行 RLock

最佳答案

您应该从另一个角度来解决问题。

一个你似乎理解得很好的简单经验法则是

You need to protect the map from concurrent accesses when at least one of them is a modification.

现在真正的问题是什么构成了 map 的修改。

要正确回答这个问题,注意存储在映射中的值是不可寻址的 — 设计使然。之所以以这种方式设计,仅仅是因为事实 map 在内部具有复杂的实现方式 might move values they contain in memory提供(摊销的)快速访问时间本地图的结构由于其元素的插入和/或删除而发生变化时。

事实 map 值不可寻址意味着您不能做像

m := make(map[int]string)
m[42] = "hello"
go mutate(&m[42]) // take a single element and go modifying it...
// ...while other parts of the program change _other_ values
m[123] = "blah blah"

不允许您这样做的原因是插入操作 m[123] = ... 可能触发移动 map 元素的存储,这可能涉及移动由 42 键控的元素的存储到内存中的其他地方——拉地毯从 goroutine 的脚下运行 mutate 函数。

因此,在 Go 中,map 实际上只支持三种操作:

  • 插入或替换元素;
  • 读取一个元素;
  • 删除一个元素。

你不能“就地”修改一个元素——你只能分三步走:

  1. 阅读元素;
  2. 修改包含(读取)副本的变量;
  3. 用修改后的副本替换元素。

正如您现在看到的,步骤 (1) 和 (3) 仅仅是 map 访问,所以你的问题的答案(希望)是显而易见的:步骤(1)应至少在读锁下完成,并且步骤(3)应在写(独占)锁下完成。


相比之下,其他复合类型的元素——struct 类型的数组(和 slice )和字段 —没有限制 map 有:提供存储“封闭”变量的位置没有被重新定位,可以通过不同的 goroutines 同时改变它的不同元素。

关于dictionary - map 内容编辑上的 Golang RWMutex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51688104/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com