Is Std::Vector or Boost::Vector Thread Safe

Is std::vector thread-safe and concurrent by default? Why or why not?

C++11 says the following about the thread safetly of containers in the standard library:

23.2.2 Container data races [container.requirements.dataraces]

For purposes of avoiding data races (17.6.5.9), implementations shall
consider the following functions to be const: begin, end,
rbegin, rend, front, back, data, find, lower_bound,
upper_bound, equal_range, at and, except in associative or
unordered associative containers, operator[].

Notwithstanding (17.6.5.9), implementations are required to avoid data
races when the contents of the contained object in different elements
in the same sequence, excepting vector<bool>, are modified
concurrently.

So, basically reading from a container from multiple threads is fine, and modifying elements that are already in the container is fine (as long as they are different elements).

So, neither of your two more specific questions are thread safe for std::vector:

1) Two threads inserting into the vector is modifying the vector itself - not existing separate elements.

2) One thread erasing and other walking to access the same element is not safe because erasing an element from the vector isn't an operation that is promised to be thread safe (or "free from data races", as the standard puts it).

To perform those operations safely will require that the program impose some external synchronization itself.

Is assignment to a std::vector element thread-safe?

Assuming your global vector is not modified by any other part of code, then your code is thread safe.

Each thread is going to write (access) into a different cell of the vector, so there is no "dirty update" problem.

Moreover the vector's type is a double, in a modern architecture is bigger than a WORD-size. So each array cell is not overlapped among others.

std::vector, thread-safety, multi-threading

Actually, it is absolutely pointless to state X is or is not thread-safe! You need to qualify for what kind of uses. For example, hardly any class will be "thread-safe" when it is somehow used in one thread and destroyed in another.

That said, the statement that std::vector<T> is not thread- safe, independent of how often it is repeated, is wrong. However, it seems most people neither understand nor appreciate the thread-safety guarantees given. std::vector<T> is thread-safe in the following sense:

  • You can read a vector object from multiple threads simultaneously.
  • If there is one thread changing a vector object, there shall be neither concurrent readers or writers.
  • Accesses to a vector object don't interfere with other vector objects.

This applies to vector structure itself. Accesses to contained object are bound to whatever rules are imposed on them. These are apparently not the thread-safety guarantees many people have in mind but anything stronger won't work with the container interface.

Filling std::vector by different threads

Related question:

Is std::vector thread-safe and concurrent by default? Why or why not?.

It's thread-safe because you're not modifying the vector size, and not attempting to write to the same memory location in different threads.

To future proof this answer for anyone who doesn't drill down into the link:

  1. It's not thread safe only because they're using the [] operator. It's thread safe because each thread is explicitly modifying a different location in memory.

  2. If all threads were only reading the same location using [], that would be thread safe.

  3. If all threads were writing to the same same location, using [] won't stop them from messing with each other.

  4. I think if this were production code, at LEAST a comment describing why this is thread safe would be called for. Not sure of any compile time way to prevent someone from shooting themselves in the foot if they modify this function.


On point #4, we want to communicate to future users of this code that:

  1. No we're not guarding this standard library container even though that should be your gut reaction, and
  2. Yes we've analyzed it and it's safe.

The easy way is to stick a comment in there, but there's a saying:

The compiler doesn't read comments and neither do I.

-Bjarne Stroustrup

I think some kind of [[attributes]] should be the way to do this? Although the built-ins don't seem to support any kind of thread safety checking.


Clang appears to provide Thread Safety Analysis:

The analysis is still under active development, but it is mature enough to be deployed in an industrial setting.

Assuming you implement other functions that would require a std::mutex to be responsible for your std::vector:

std::mutex _mu;
std::vector<int> _vec GUARDED_BY(_mu);

then you can explicitly add the NO_THREAD_SAFETY_ANALYSIS attribute to turn off the safety checking for this one specific function. I think it's best to combine this with a comment:

// I know this doesn't look safe but it is as long as
// the caller always launches it with different values of `i`
void foo(int i, std::vector<int>& vec) NO_THREAD_SAFETY_ANALYSIS;

The use of GUARDED_BY tells me, in the future, that you are thinking about thread safety. The use of NO_THREAD_SAFETY_ANALYSIS shows me that you have determined this function is okay to use - especially when other functions that modify your vector are not marked NO_THREAD_SAFETY_ANALYSIS.



Related Topics



Leave a reply



Submit