以原子方式访问存储在映射中的资源

Atomically accessing resources stored in a map

本文关键字:映射 资源 存储 方式 访问      更新时间:2023-10-16

我想使用整数键将一些std::shared_ptr到C++类实例存储在映射中,例如std::映射。然而,我需要这个地图有两个属性:

  1. 如果键不存在,则返回一个错误,而不是创建一个新对象
  2. 如果密钥确实存在,那么以原子方式获取std::shared_ptr的副本。也就是说,不可能在一个线程中从映射中删除对象,同时在另一个线程从映射中检索对象

如果可能的话,我希望避免使用单个互斥(甚至是多读、单写(来从映射中获取和删除对象,以避免开销。

这样的map类在任何库中都存在吗?如果没有,你能建议如何实施吗?

如果集合中的元素具有互斥对象,则可以简单地使用无锁数据结构。在boost 1.53.0中的C++中实现了。

然而,我建议再次考虑互斥锁——在许多情况下,它们将提供更好的性能——无锁数据结构(尽管并非总是如此(,并且更容易管理。只要没有互斥对象的循环,你就应该没事。

在不创建的情况下访问时,如果使用C++03(返回迭代器(,请使用std::map::find;如果使用C++11(返回引用(,则使用std::map::at。

EDIT:实际上std::map::at可能更糟,除非您假设正常情况下元素存在(即,违反仅对异常状态而非正常操作使用异常的规则(。然而,这可能也取决于适用于例外情况的哲学。

1(使用std::map::at。如果密钥不存在,则会引发异常

2( 使用活动对象访问地图。活动对象负责序列化操作,从而避免竞争条件,但允许您使用普通的旧std::map