简体   繁体   English

std::vector emplace_back 和 push_back 是线程安全的吗

[英]Are std::vector emplace_back and push_back thread-safe

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?如果我有一个 function 仅在具有 unique_ptr 作为值的全局向量上执行 emplace_back 或 push_back,它是线程安全的还是我必须使用互斥锁? 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?如果它只是 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.有关标准容器的线程安全性,请参阅cppreference

Consider this toy example that illustrates the critical part that eg a vector<int>::push_back might do:考虑这个玩具示例,它说明了例如vector<int>::push_back可能做的关键部分:

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. std::vector肯定不是broken_toy_vector ,但是当新大小超过当前容量时,向量需要重新分配。 There is no good reason for std::vector to make push_back thread-safe, because that would incur overhead in any single-threaded usage. std::vector没有充分的理由使push_back线程安全,因为这会在任何单线程使用中产生开销。 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 TL;博士

No. It is not safe to call std::vector::push_back concurrently from different threads.不,从不同线程同时调用std::vector::push_back是不安全的。 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.保护对其数据的任何访问的容器的用途有限,因为用户无法控制锁定的粒度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM