我遇到了罕见的程序崩溃,我相信(我相当确定)在调整跨线程访问的 vector 大小时会发生这种情况。我在推回函数中添加了一个互斥体(如下)。我想我可能会看到某些情况,其中导致 vector 在另一个线程 X 中调整大小,而线程 Y 试图从 vector 成员之一复制值 - 这会导致复制的大小为 0,稍后会导致 std::out_of_range 访问权限。
class TvectorPM {
public:
pthread_mutex_t lock;
std::vector<PopulationMember> v;
TvectorPM();
virtual ~TvectorPM();
void add(PopulationMember p);
};
void TvectorPM::add(PopulationMember p) {
pthread_mutex_lock(&lock);
v.push_back(p);
pthread_mutex_unlock(&lock);
}
我不热衷于为 vector 读取添加互斥体,因为代码中的大多数地方只需要读取,而性能对于该软件来说是一个大问题。下面是正在发生的事情的伪示例
void EvolutionManager::mutateSingleNode(int num_needed, int pool_size) {
#pragma omp parallel
{
#pragma omp for schedule(dynamic) nowait
for (int x = 0; x < num_needed; x ++) {
// Copy the original RPN Vec, create a new member
int rand_member = tornament(pool_size);
PopulationMember p;
p.rpn_node_vec = population_manager.populationlist.v.at(rand_member).rpn_node_vec;
p.change();
population_manager.populationlist.add(p);
}
}
}
我觉得我可以
a) - 承受性能损失并互斥读取
b) - 检查 p.rpn_node_vec 的大小是否 > 0 或重新读取(再次影响性能,并且很hacky)
c) - 请教各位好心人,是否有办法在开始循环之前为 vector 分配额外的内存以避免调整大小?
最佳答案
如果你想为 vector 预分配内存,有几种方法可以实现:
// constructor parameter, creates 100 default constructed objects
// giving v1.size() == 100;
std::vector<int> v1(100);
std::vector<int> v2;
// resize() will actually resize the vector making size match the parameter passed in
v2.resize(100);
// again, v2.size() == 100;
std::vector<int> v3;
// reserve just "sets aside" memory for the vector to use later
v3.reserve(100);
// now, v3.size() == 0, but v3.capacity() == 100
关于c++ - std::vector - 线程安全和调整大小选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20413675/