Atomically accessing resources stored in a map

2019-08-02 08:57发布

I want to store some std::shared_ptr to C++ class instances in a map, e.g. a std::map, using an integer key. However, I need this map to have two properties:

  1. If the key doesn't exist, then return an error rather than create a new object.
  2. If the key does exist then grab a copy of the std::shared_ptr atomically. I.e. it should not be possible to delete an object from the map in one thread while simultaneously retrieving it from the map in another.

I'd like to avoid having a single mutex (even multiple read, single write) for getting and removing objects from the map if possible, to avoid the overhead.

Does such a map class exist in any library? If not, can you suggest how to implement one?

2条回答
Bombasti
2楼-- · 2019-08-02 09:01

1) Use std::map::at. That will raise an exception if the key is not present

2) Use an active object to access the map. The active object takes care of serializing operations and thus avoiding race conditions, yet allows you to use a plain old std::map.

查看更多
Fickle 薄情
3楼-- · 2019-08-02 09:11

If the elements inside the collection have mutexes you can simply use lock-free data structures. There are implemented in C++ in boost 1.53.0.

However I would advice to look at mutexes once again - in many cases they will offer better performance the lock-free data structure (although not always) and are much easier to manage. As long as there is no loop of mutexes you should be fine.

As of access-without-creation use std::map::find if you use C++03 (returns iterator) or std::map::at if you use C++11 (returns reference).

EDIT: Actually std::map::at is possibly worse unless you assume that the normal case is that element is present (i.e. against rule to use exceptions only for exceptional state instead of normal operation). However it probably depends also on philosophy one applies to exceptions.

查看更多
登录 后发表回答