Damir Tenishev
Damir Tenishev

Reputation: 3402

How to store std::shared_ptr in std::vector in thread-safe way?

I have many threads which share access to the same pool of objects, and some threads could remove objects, so I use std::vector<std::shared_ptr<T>> to hold pointers to the objects so that objects are released when no longer needed by any threads.

I keep the size of the pool constant (the maximum amount of objects is known at start) and just zero the pointers to "removed" objects.

With the deprecation of std::atomic_...<std::shared_ptr>, I have to use class template specialization std::atomic<std::shared_ptr>, which gets me back to std::atomic which doesn't have a copy constructor and therefore can't be stored in std::vector.

So, the only way is to use the following container to deal with this:

struct T {};
std::vector<std::unique_ptr<std::atomic<std::shared_ptr<T>>>> pool;

I understand that "We can solve any problem by introducing an extra level of indirection", but this seems to be "way too much"; this is not only extra pointers and memory allocations, this makes the code hard to write and read with so many indirections.

Is there a recommended way to store a pool of objects with C++ in a multi-threaded environment?

Or, should I get back to one of the simplest solutions like storing reference counters (or states like "released", in my case) in my objects (or in a parallel array) together with:

  1. Storing plain objects in the array, which is really not good to combine with polymorphic class hierarchies, produces hard-to manage code, and gives hard times to use lock-free approaches.
  2. Store plain pointers.

Am I missing some new approach for this, which comes together with moving to std::atomic<std::shared_ptr> to have this in a straight-forward way, reusing existing stuff from C++ and std?

Of course, I can still use std::shared_ptr<T> with mutexes and so on, but I want to have a solid solution with the smallest number of used components, and approach closer to a lock-free architecture (I know that std::atomic is not lock-free) as possible.

Upvotes: 3

Views: 118

Answers (0)

Related Questions