编写std :: vector与普通数组的线程安全性 [英] Thread-safety of writing a std::vector vs plain array

查看:140
本文介绍了编写std :: vector与普通数组的线程安全性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Stackoverflow上已阅读 ,其中STL容器具有写线程安全性.但是,这实际上意味着什么呢?这是否意味着我应该将可写数据存储在纯数组中?

I've read on Stackoverflow that none of the STL containers are thread-safe for writing. But what does that mean in practice? Does it mean I should store writable data in plain arrays?

我希望同时调用 std :: vector :: push_back(element)可能导致数据结构不一致,因为它可能需要调整向量的大小.但是像这样的情况呢,其中不涉及调整大小:

I expect concurrent calls to std::vector::push_back(element) could lead to inconsistent data structures becaue it might entail resizing the vector. But what about a case like this, where resizing is not involved:

  1. 使用数组:

int data[n];
// initialize values here...

#pragma omp parallel for
for (int i = 0; i < n; ++i) {
    data[i] += func(i);
}

  1. 使用`std :: vector``:

std::vector<int> data;
data.resize(n);
// initialize values here...
    
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
    data[i] += func(i);
}

第一个实现在线程安全性和b)在性能方面真的比第二个实现好吗?我宁愿使用std :: vector,因为我对C样式的数组不太满意.

Is the first implementation really better than the second one a) in terms of thread-safety and b) in terms of performance? I would prefer to use a std::vector, since I am less comfortable with C-style arrays.

我删除了保护代码的 #pragma omp原子更新.

推荐答案

两者同样安全.如果没有从多个线程访问任何元素,就可以了.您的并行循环将只访问一次每个元素,因此只能从一个线程访问.

The two are equally safe. Provided no element is accessed from multiple threads you're OK. Your parallel loop will access each element only once, and hence only from one thread.

标准中的空间要求容器的成员函数是非线程安全的.在这种情况下,您使用 vector< int> :: operator [] ,因此您需要为该成员提供明确的线程安全保证,这似乎是合理的,因为即使在非const上调用它也是如此.vector不会修改vector本身.因此,我怀疑在这种情况下是否存在问题,但我没有寻找保证.即使可能不安全,您也可以在循环之前执行 int * dataptr =& data.front(),然后索引 dataptr 而不是 data .

There's space in the standard for the member functions of containers to be non-thread-safe. In this case you use vector<int>::operator[], so you'd want an explicit guarantee of thread-safety for that member, which seems reasonable since calling it even on a non-const vector doesn't modify the vector itself. So I doubt that there's a problem in this case, but I haven't looked for the guarantee [edit: rici found it]. Even if it's potentially unsafe, you could do int *dataptr = &data.front() before the loop and then index off dataptr instead of data.

顺便说一句,对于 vector< bool> ,此代码对于 vector< bool> 是不能保证安全的,因为这是一种特殊情况,多个元素共存于一个对象中.对于数组 bool 来说是安全的,因为其中的不同元素是不同的内存位置"(在C ++ 11中为1.7).

As an aside, this code is not guaranteed safe for vector<bool>, since it's a special-case for which multiple elements co-exist inside one object. It would be safe for an array of bool, since the different elements of that are different "memory locations" (1.7 in C++11).

这篇关于编写std :: vector与普通数组的线程安全性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆