Let me start by saying that I have read most SO and other topics on the subject.
The way I understand things, std::vector will reallocate memory when pushing back new items, which is my case, unless I have reserved enough space (which is not my case).
What I have is a vector of std::shared_ptr, and that vector holds unique objects (or more correctly, pointers to unique objects in the vector).
The handling of those objects via pointers is wrapped around a Factory & Handler class, but pointers to the objects are accessible from outside the wrapper class and can have member values modified. There is no deleting happening at any time.
If I am understanding correctly issues raised in previous SO questions about std::vector and thread safety, adding (push_back) new objects may invalidate previous pointers, as the vector internally may reallocate memory and copy everything over, which would of course be a disaster for me.
My intentions are to read from that vector, often modifying objects through the pointers, and add new items to the vector, from threads running asynchronously.
So,
If it is of any importance, all the above is on linux (debian jessie) using gcc-4.8 with c++11 enabled.
I am open to using minimally invasive libraries.
Many thanks in advance :-)
Vectors are synchronized. Any method that touches the Vector 's contents is thread safe. ArrayList , on the other hand, is unsynchronized, making them, therefore, not thread safe.
const and Thread Safety The C++11 standard does not expect to be able to safely call non const functions simultaneously. Therefore all classes available from the standard, e.g. std::vector<>, can safely be accessed from multiple threads in the same manner.
The collection classes that are thread-safe in Java are Stack, Vector, Properties, Hashtable, etc.
This operation mutates state and therefore is not const , but the mutation is guaranteed to be atomic, and is therefore thread-safe.
adding (push_back) new objects may invalidate previous pointers ...
No, this operation doesn't invalidate any previous pointers, unless you are refering to addresses inside the vectors internal data management (which clearly isn't your scenario).
If you store raw pointers, or std::shared_ptr
's there, those will be simply copied, and not get invalid.
As mentioned in comments a std::vector
isn't very suitable to guarantee thread safety for producer / consumer patterns for a number of reasons. Neither storing raw pointers to reference the alive instances is!
A Queue will be much better to support this. As for standards you can use the std::deque
to have ceratain access points (front()
,back()
) for the producer / consumer.
To make these access point's thread safe (for pushing/popping values) you can easily wrap them with your own class and use a mutex along, to secure insertion/deletion operations on the shared queue reference.
The other (and major, as from your question) point is: manage ownership and lifetime of the contained/referenced instances. You may also transfer ownership to the consumer, if that's suitable for your use case (thus getting off from the overhead with e.g. std::unique_ptr
), see below ...
Additionally you may have a semaphore (condition variable), to notify the consumer thread, that new data is available.
'1. Using atomic or mutexes is not enough? If I push back from one thread, another thread handling an object via pointer may end up having an invalid object?'
The lifetime (and thus thread safe use) of the instances stored to the queue (shared container) need's to be managed separately (e.g. using smart pointers like std::shared_ptr
or std::unique_ptr
stored there).
'2. Is there a library ...'
It can be achieved all well with the existing standard library mechanisms IMHO.
As for point 3. see what's written above. As what I can tell further about this, it sounds like you're asking for something like a rw_lock
mutex. You may provide a surrogate for this with a suitable condition variable.
Feel free to ask for more clarification ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With