【发布时间】:2016-07-10 02:18:48
【问题描述】:
根据 Go 博客,
地图对于并发使用是不安全的:它没有定义当您同时读取和写入它们时会发生什么。如果您需要从并发执行的 goroutine 中读取和写入映射,则必须通过某种同步机制来调节访问。 (来源:https://blog.golang.org/go-maps-in-action)
谁能详细说明一下?跨例程似乎允许并发读取操作,但如果尝试读取和写入同一个键,并发读取/写入操作可能会产生竞争条件。
在某些情况下可以降低最后一个风险吗?例如:
- 函数 A 生成 k 并设置 m[k]=0。这是 A 唯一一次写入映射 m。已知 k 不在 m 中。
- A 将 k 传递给同时运行的函数 B
- A 然后读取 m[k]。如果 m[k]==0,它会等待,仅当 m[k]!=0 时才继续
- B 在地图中寻找 k。如果找到它,B 将 m[k] 设置为某个正整数。如果不是,它会等到 k 在 m 中。
这不是代码(显然),但我认为它显示了即使 A 和 B 都尝试访问 m 也不会出现竞争条件,或者如果存在则无关紧要的情况的轮廓因为额外的限制。
【问题讨论】:
-
使用竞争检测器运行您的代码。
-
不安全。转到 1.6 added a best-effort detection of concurrent misuse of maps。当检测到误用时,运行时会导致程序崩溃。
-
问:“在某些情况下,最后的风险可以降低吗?”答:“不”。
标签: go concurrency hashmap