concurrent_vector

concurrent_vector#

A concurrent_vector<T> is a dynamically growable array of T. It is safe to grow a concurrent_vector while other threads are also operating on elements of it, or even growing it themselves. For safe concurrent growing, concurrent_vector has three methods that support common uses of dynamic arrays: push_back, grow_by, and grow_to_at_least.

Method push_back(x) safely appends x to the array. Method grow_by(n) safely appends n consecutive elements initialized with T(). Both methods return an iterator pointing to the first appended element. Each element is initialized with T(). So for example, the following routine safely appends a C string to a shared vector:

void Append( concurrent_vector<char>& vector, const char* string ) {
    size_t n = strlen(string)+1;
    std::copy( string, string+n, vector.grow_by(n) );
}

The related method grow_to_at_least(n)grows a vector to size n if it is shorter. Concurrent calls to the growth methods do not necessarily return in the order that elements are appended to the vector.

Method size() returns the number of elements in the vector, which may include elements that are still undergoing concurrent construction by methods push_back, grow_by, or grow_to_at_least. The example uses std::copy and iterators, not strcpy and pointers, because elements in a concurrent_vector might not be at consecutive addresses. It is safe to use the iterators while the concurrent_vector is being grown, as long as the iterators never go past the current value of end(). However, the iterator may reference an element undergoing concurrent construction. You must synchronize construction and access.

A concurrent_vector<T> never moves an element until the array is cleared, which can be an advantage over the STL std::vector even for single-threaded code. However, concurrent_vector does have more overhead than std::vector. Use concurrent_vector only if you really need the ability to dynamically resize it while other accesses are (or might be) in flight, or require that an element never move.

Caution

Operations on concurrent_vector are concurrency safe with respect to growing, not for clearing or destroying a vector. Never invoke method clear() if there are other operations in flight on the concurrent_vector.