在我的代码中存储配置的常见模式是受 RWMutex 保护的“map[string]interface{}”,但通常在应用启动后(可以在多个 go-routine 中触发),地图变得完全只读。所以我有一种感觉,从某个时间点开始,读取时的 RWMutex 应该是不必要的。此配置映射的示例位于 http://play.golang.org/p/tkbj9DBok_让我想到这一点的一个事实是,在一些生产代码中,它实际上以这种方式对共享对象进行了不受保护的访问(尽管它在初始化后主要是只读的),我理解使用 RWMutex 进行保护的正常方式,但很有趣部分是这种格式错误的代码在过去几个月没有遇到问题。在某个准确的“时间点”之后,写入从缓存刷新到内存并保证不再需要写入后,读取实际上可以在没有 RWMutex.RLock 的情况下进行,这是真的吗?如果是,无锁访问前的时间点或如何设置条件?
2 回答
LEATH
TA贡献1936条经验 获得超6个赞
只要没有人修改地图,多个线程一次读取它应该是安全的。不幸的是,如果没有任何锁定,您将无法确保在您想要更新地图时没有其他人正在阅读地图。
因此,一种解决方案是永远不要更新地图,而是以原子方式替换它。该只读副本更新算法可以在这里使用。而不是直接访问地图,因此您需要取消引用指针才能访问地图。要更新它,您可以执行以下操作:
获取“更新锁”互斥锁。
制作地图的副本。你想手动复制所有的键/值:简单的赋值是行不通的,因为映射是引用类型。
对地图副本进行更改。
使用
StorePointer
从sync/atomic
包中自动更新指向实时地图的指针以指向您的新地图。释放互斥锁。
在 (4) 中原子更新之前运行的所有内容都将看到旧地图,之后的所有内容都将看到新地图。这些 goroutine 绝不会从正在写入的地图中读取数据,因此不需要RWMutex
.
- 2 回答
- 0 关注
- 226 浏览
添加回答
举报
0/150
提交
取消