std :: vector push_back在并行for循环中使用时失败

时间:2013-10-09 09:34:30

标签: c++ vector parallel-processing thread-safety openmp

我有一个如下代码(简化代码):

for( int i = 0; i < input.rows; i++ )
{
    if(IsGoodMatch(input[I])
    { 
        Newvalues newValues;
        newValues.x1=input.x1;
        newValues.x2=input.x1*2;
        output.push_back( newValues);
    }
} 

这段代码运行良好,但如果我想使用omp parallel for使其并行,我在output.push_back上遇到错误,似乎在向量调整大小时,内存已损坏。

问题是什么,我该如何解决?

如何确保任何时候只有一个线程将新项目插入到矢量中?

5 个答案:

答案 0 :(得分:6)

std::vector的{​​{1}}无法保证在以与您现在正在执行的并发方式调用时的正确行为(没有线程安全性)。

然而,由于元素不相互依赖,因此push_back向量并分别修改循环内的元素是非常合理的:

resize

因为使用output.resize(input.rows); int k = 0; #pragma omp parallel for shared(k, input) for( int i = 0; i < input.rows; i++ ) { if(IsGoodMatch(input[I]) { Newvalues newValues; ... // ! prevent other threads to modify k ! output[k] = newValues; k++; // ! allow other threads to modify k again ! } } output.resize(k); 的直接访问不依赖于operator[]的其他成员,这可能导致线程之间的不一致。 但是此解决方案可能仍需要显式同步(即使用互斥机制等同步机制),以确保使用正确的std::vector值。

“我怎样才能确保任何时候只有一个线程将新项目插入到矢量中?”

你不需要。线程将修改不同的元素(驻留在内存的不同部分)。您只需要确保每个线程尝试修改的元素都是正确的元素。

答案 1 :(得分:6)

简单的答案是std::vector::push_back不是线程安全的。

为了安全地并行执行此操作,您需要进行同步,以确保不会同时从多个线程调用push_back

使用std::mutex可以轻松实现C ++ 11中的同步。

答案 2 :(得分:2)

#pragma omp critical之前放置push_back

答案 3 :(得分:0)

使用并发向量

#include <concurrent_vector.h>
c ++ 11中的

Concurrency::concurrent_vector<int>

它是矢量的线程安全版本。

答案 4 :(得分:-8)

您可以尝试使用互斥锁来解决问题。 通常我更喜欢自己做这件事;

static int mutex=1;
int signal(int &x)
{
    x+=1;
    return 0;
}
int wait(int &x)
{
    x-=1;
    while(x<0);
    return 0;
}
for( int i = 0; i < input.rows; i++ )
{
    if(IsGoodMatch(input[I])
    {
        Newvalues newValues;
        newValues.x1=input.x1;
        newValues.x2=input.x1*2;
        wait(mutex);
        output.push_back( newValues);
        signal(mutex);
    }
} 

希望这可以提供帮助。