If I have a function that only do emplace_back or push_back on a global vector with unique_ptr as a values, will it be thread-safe or I have to use mutexes? Is mutex the only way to make it thread safe?
void (T param)
{
globalVector.emplace_back(std::make_unique<T>(param));
//or globalVector.push_back (std::make_unique<T>(param));
}
And if it only be vector of T?
void (T param)
{
globalVector.emplace_back(param);
//or globalVector.push_back (param);
}
will it be thread-safe
No
or I have to use mutexes?
Yes
See cppreference for thread-safety of standard containers.
Consider this toy example that illustrates the critical part that eg a vector<int>::push_back
might do:
struct broken_toy_vector {
size_t size;
size_t capacity;
int* data;
void push_back(int x){
if (size+1 > capacity) {
int* temp = new int[size+1];
// copy from data to temp
temp[size] = x;
size += 1;
delete data;
data = temp;
} else {
throw "not implemented";
}
}
};
A std::vector
is surely not a broken_toy_vector
, but when the new size exceeds current capacity then a vector needs to reallocate. There is no good reason for std::vector
to make push_back
thread-safe, because that would incur overhead in any single-threaded usage. Further, also with more than one thread, often you don't want synchronisation on the lowest level. Consider:
for (int i=0; i<1000; ++i) {
vect.push_back(i);
}
Locking a mutex in every iteration would be extremely wasteful.
TL;DR
No. It is not safe to call std::vector::push_back
concurrently from different threads. A container that protects any acces to its data, would be of limited use, because the user has no control over granularity of the locking.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.