假设我有一个2D数组和这个函数:
void addVec(std::vector<std::vector<short> >& arr, size_t idx){
arr[idx].push_back(idx);
}
std::vector<std::vector<short> > arr(2);
boost::threads th1(addVec, boost::ref(arr), 0);
boost::threads th2(addVec, booost::ref(arr), 1);
th1.join();
th2.join();
到现在我应该有arr [0] [0] = 0;和arr [1] [0] = 1; 问题是这是否安全? 在内部,线程应该向向量存储器的不同部分添加值,并且因为它是在大小2的开头构造的,所以只有内部向量被调整大小,具有线程独占访问权。
答案 0 :(得分:4)
这应该是安全的,因为每个线程访问一个单独的向量。但是,如果你做了任何可能导致arr
调整大小的事情,那么所有的赌注都会被取消......
答案 1 :(得分:4)
我建议您退后一步,考虑一下您的目标是什么,然后再继续沿着您的目标前进。
首先,您为什么要并行化代码?我假设你希望你的程序运行得更快。这意味着
要点1.和2.可能就是你应该投入时间的地方。可能的情况是,高度调整的顺序实现已经足以满足您的需求,并且开发和维护将更加便宜/更容易/更快。
如果您决定并行化代码,则应该查看OpenMP。线程可能是编写人类已知并行程序的最糟糕方法之一。您可能认为OpenMP的运行时系统对您而言太慢了,但您应该退一步思考原因。
如果您的算法需要大量锁定和障碍,则可以通过使用更快的锁定和障碍来获得较小的加速。如果您将算法改进为使用更少的锁和障碍,则可以实现更大的加速。
答案 2 :(得分:2)
这是安全的,尽管从设计的角度来看,给每个线程只提供其内部向量会更安全,因此未来不安全行为的可能性较小
答案 3 :(得分:2)
是的,在您的使用案例中它是安全的,因为您不会修改共享数据。但是,我更愿意将std::vector<short>
的引用传递给每个线程以简化用法:
void addVec(std::vector<short> & arr)
{
arr.push_back(some_data);
}
std::vector<std::vector<short> > arr(2);
boost::threads th1(addVec, boost::ref(arr[0]));
boost::threads th2(addVec, booost::ref(arr[1]));
th1.join();
th2.join();