In my program I've some threads running. Each thread gets a pointer to some object (in my program - vector). And each thread modifies the vector.
And sometimes my program fails with a segm-fault. I thought it occurred because thread A begins doing something with the vector while thread B hasn't finished operating with it? Can it bee true?
How am I supposed to fix it? Thread synchronization? Or maybe make a flag VectorIsInUse
and set this flag to true while operating with it?
vector
, like all STL containers, is not thread-safe. You have to explicitly manage the synchronization yourself. A std::mutex
or boost::mutex
could be use to synchronize access to the vector
.
Do not use a flag as this is not thread-safe:
- Thread A checks value of
isInUse
flag and it is false
- Thread A is suspended
- Thread B checks value of
isInUse
flag and it is false
- Thread B sets
isInUse
to true
- Thread B is suspended
- Thread A is resumed
- Thread A still thinks
isInUse
is false
and sets it true
- Thread A and Thread B now both have access to the
vector
Note that each thread will have to lock the vector
for the entire time it needs to use it. This includes modifying the vector
and using the vector
's iterators as iterators can become invalidated if the element they refer to is erase()
or the vector
undergoes an internal reallocation. For example do not:
mtx.lock();
std::vector<std::string>::iterator i = the_vector.begin();
mtx.unlock();
// 'i' can become invalid if the `vector` is modified.
If you want a container that is safe to use from many threads, you need to use a container that is explicitly designed for the purpose. The interface of the Standard containers is not designed for concurrent mutation or any kind of concurrency, and you cannot just throw a lock at the problem.
You need something like TBB or PPL which has concurrent_vector
in it.
That's why pretty much every class library that offers threads also has synchronization primitives such as mutexes/locks. You need to setup one of these, and aquire/release the lock around every operation on the shared item (read AND write operations, since you need to prevent reads from occuring during a write too, not just preventing multiple writes happening concurrently).