微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决std::vector emplace_back 和 push_back 是线程安全的

如果我有一个函数只对全局向量执行 emplace_back 或 push_back,并将 unique_ptr 作为值,它是线程安全的还是我必须使用互斥锁?互斥量是确保线程安全的唯一方法吗?

void (T param)
{
globalVector.emplace_back(std::make_unique<T>(param));
//or globalVector.push_back (std::make_unique<T>(param));
}

如果它只是 T 的向量?

void (T param)
{
globalVector.emplace_back(param);
//or globalVector.push_back (param);
}

解决方法

是否是线程安全的

没有

还是我必须使用互斥锁?

是的

有关标准容器的线程安全性,请参阅 cppreference

,

考虑这个玩具示例,它说明了例如 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 肯定不是 broken_toy_vector,但是当新大小超过当前容量时,向量需要重新分配。 std::vector 没有充分的理由使 push_back 线程安全,因为这会在任何单线程使用中产生开销。此外,对于多个线程,通常您不希望在最低级别进行同步。考虑:

 for (int i=0; i<1000; ++i) {
      vect.push_back(i);
 }

在每次迭代中锁定互斥锁会非常浪费。

TL;博士

没有。从不同线程并发调用 std::vector::push_back 是不安全的。保护对其数据的任何访问的容器的用途有限,因为用户无法控制锁定的粒度。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。