高龙并发地图访问范围 [英] Golang concurrent map access with range

查看:129
本文介绍了高龙并发地图访问范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在清除地图之前,我有一个需要释放的对象的地图。我试着在地图上迭代并删除/释放对象。

I have a map with objects that needs to be released before clearing the map. I am tempted to iterate over the map and remove/release objects as I walk through it.

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

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

Since the only way to iterate the map is through range, how would I synchronize multiple producers and multiple consumers?

我不想读取锁定地图,因为那个将在迭代过程中删除/修改密钥不可能。

I don't want to read lock the map since that would make delete/modifying keys during the iteration impossible.

推荐答案

有一些方法可以从 map 没有racy地图访问。适用于您的应用程序取决于它在做什么。

There are a bunch of ways you can clean up things from a map without racy map accesses. What works for your application depends a lot on what it's doing.

0)只需在工作时锁定地图即可。如果地图不是太大,或者你有一些延迟宽容,它可以快速完成工作(根据时间花费),您可以继续思考其他内容。如果以后出现问题,您可以再回到问题。

0) Just lock the map while you work on it. If the map's not too big, or you have some latency tolerance, it gets the job done quickly (in terms of time you spend on it) and you can move on to thinking about other stuff. If it becomes a problem later, you can come back to the problem then.

1)复制对象或指针,并按住锁定清除地图,然后释放背景中的对象。如果问题是缓慢释放本身会使锁持续很长时间,这是简单的解决方法。

1) Copy the objects or pointers out and clear the map while holding a lock, then release the objects in the background. If the problem is that the slowness of releasing itself will keep the lock held a long time, this is the simple workaround for that.

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

2) If efficient reads are basically all that matters, use atomic.Value. That lets you entirely replace one map with a new and different one. If writes are essentially 0% of your workload, the efficient reads balance out the cost of creating a new map on every change. That's rare, but it happens, e.g., encoding/gob has a global map of types managed this way.

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

3) If none of those do everything you need, tweak how you store the data (e.g. shard the map). Replace your map with 16 maps and hash keys yourself to decide which map a thing belongs in, and then you can lock one shard at a time, for cleanup or any other write.

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

There's also the issue of a race between release and use: goroutine A gets something from the map, B clears the map and releases the thing, A uses the released thing.

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

One strategy there is to lock each value while you use or release it; then you need locks but not global ones.

另一个是容忍如果已知而不是灾难性的比赛的后果;例如,其文档明确允许并发访问 net.Conn ,因此关闭使用中的连接可能会导致请求发生错误但不会导致到未定义的应用程序行为。尽管如此,你必须确定你知道你在做什么,因为许多良性的比赛不是

Another is to tolerate the consequences of races if they're known and not disastrous; for example, concurrent access to net.Conns is explicitly allowed by its docs, so closing an in-use connection may cause a request on it to error but won't lead to undefined app behavior. You have to really be sure you know what you're getting into then, though, 'cause many benign-seeming races aren't.

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

Finally, maybe your application already is ensuring no in-use objects are released, e.g. there's a safely maintained reference count on objects and only unused objects are released. Then, of course, you don't have to worry.

尝试用渠道替换这些锁可能是诱人的,但我没有看到任何收益它。当您可以设计您的应用程序思想时,主要是根据进程之间的通信而不是共享数据来设计您的应用程序,但是当您有共享数据时,没有任何用处。排除对共享数据的不安全访问是什么锁。

It may be tempting to try to replace these locks with channels somehow but I don't see any gains from it. It's nice when you can design your app thinking mainly in terms of communication between processes rather than shared data, but when you do have shared data, there's no use in pretending otherwise. Excluding unsafe access to shared data is what locks are for.

这篇关于高龙并发地图访问范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆