数据结构 – Golang并发地图访问与范围

前端之家收集整理的这篇文章主要介绍了数据结构 – Golang并发地图访问与范围前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一张地图,需要在清除地图之前释放对象.当我走过它时,我试图迭代地图并删除/释放对象.

这是一个模拟的例子
https://play.golang.org/p/kAtPoUgMsq

由于迭代地图的唯一方法是通过范围,我如何同步多个生产者和多个消费者?

我不想读取锁定地图,因为这将使迭代中的删除/修改键不可能.

有一些方法可以从地图中清除东西,而不需要访问地图.适用于您的应用程序取决于它在做什么.

0)只要你在工作时锁定地图.如果地图不是太大,或者你有一些延迟宽容,它可以快速完成工作(在你花费的时间上),你可以继续思考其他的东西.如果以后出现问题,那么可以回到问题.

1)复制对象或指针并按住锁定清除地图,然后在后台释放对象.如果问题是释放缓慢会使锁持续很长时间,那就是简单的解决办法.

2)如果高效的读取基本上都是重要的,请使用atomic.Value.这可以让您完全用一个新的和不同的地图替换一个地图.如果写入本质上是您的工作负载的0%,高效读取可以平衡每个更改创建新映射的成本.这很罕见,但它发生,例如,encoding / gob具有以这种方式管理的类型的全局映射.

3)如果没有人做任何你需要的一切,调整你如何存储数据(例如划分地图).用16个地图和散列键自动替换地图,以决定一个属于哪个地图,然后一次可以锁定一个碎片,以进行清理或其他任何写入操作.

还有一个发布和使用之间的竞争的问题:goroutine A从地图获取东西,B清除地图并释放该东西,A使用发布的东西.

一个策略是在使用或释放​​它时锁定每个值;那么你需要锁,而不是全局锁.

另一个原因是容忍种族的后果,如果它们是已知的,而不是灾难性的;例如,net.Conns的并发访问权限由其文档明确允许,因此关闭使用中的连接可能会导致请求发生错误,但不会导致未定义的应用程序行为.你必须真的确定你知道你在做什么,但是,因为many benign-seeming races aren’t.

最后,也许您的应用程序已经确保没有使用对象被释放,例如对象上有一个安全维护的引用计数,只释放未使用的对象.那么当然,你不必担心.

尝试用渠道替代这些锁可能是诱人的,但我看不到任何收获.很好,当您可以设计您的应用程序思想时,主要是在进程之间的通信而不是共享数据,但是当您有共享数据时,没有用于假装.排除对共享数据的不安全访问是什么锁.

猜你在找的Go相关文章