Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write concurrently vector<bool>

I know that is possible to read concurrently from a std::vector without "bad" consequences because this operation can be considered thread-safe.

But the same cannot be said for writing operations. But, I am wondering if this is not always true, for example considering my particular scenario.

I have a std::vector<bool>, where all the elements are initialized to false, and, given an array of indices, I need to change the value of these elements (vector[index] for each index) from false to true.

If I use a different thread for each index (and there is the possibility that some indices have the same value), can this operation be considered thread-safe?

If the vector is a std::vector<int> (or any primitive type) and the value assigned is always the same (for example 1) can this operation still be considered thread-safe?

like image 294
Nick Avatar asked Nov 09 '15 20:11

Nick


People also ask

What is a vector bool?

The vector<bool> class is a partial specialization of vector for elements of type bool . It has an allocator for the underlying type that's used by the specialization, which provides space optimization by storing one bool value per bit.

Is STD Vector contiguous?

Yes, the elements of a std::vector are guaranteed to be contiguous.


1 Answers

Concurrent writes to vector<bool> are never ok, because the underlying implementation relies on a proxy object of type vector<bool>::reference which acts as if it was a reference to bool, but in reality will fetch and update the bitfield bytes as needed.

When using multiple threads without synchronization, the following might happen: Thread 1 is supposed to update a bit, and reads the byte containing it. Then thread 2 reads the same byte, then thread 1 updates a bit and writes the byte back, and then thread 2 updates another bit and writes the byte back, overwriting the edit of thread 1.

This is just one possible scenario, there are others that would lead to the same kind of data corruption.


In the vector<int> situation, if you are absolutely sure that all threads write the same value into the vector, then this operation will generally not lead to data corruption. However, the standard is of course always extra careful and defines all concurrent accesses to a memory location, of which at least one is a write access, to be undefined behavior:

Two expression evaluations conflict if one of them modifies a memory location and the other one reads or modifies the same memory location. – intro.races/2

Therefore, as soon as you do any modification operation on the same element from two different threads, you will have a race condition and need proper synchronization, e.g. by using std::atomic<int>.

like image 111
Felix Dombek Avatar answered Oct 15 '22 19:10

Felix Dombek