在唯一指针映射上打开mp循环

时间:2018-10-04 09:56:19

标签: c++ pointers segmentation-fault unique-ptr stdmap

我正在尝试遍历包含唯一指针作为值的映射。这是实现。代码可以编译,没问题。

#include <iostream>
#include <map>
#include <memory>
#include <vector>
#include <omp.h>

class test_class
{
public:
    test_class(int Id, double Td)
    {
        mId = Id;
        mTd = Td;
    }
    void update(double Utd)
    {
        mTd += Utd;
    }
    void print()
    {
        std::cout<<"test_class :: "<<mId<<" Td :: "<<mTd<<std::endl;
    }
private:
    double mTd;
    int mId;
};


typedef std::map< int, std::unique_ptr<test_class> > MapType;
int main() {
    MapType map_u_prt;
    std::vector<int> vec_ids = {1,2,6,5,8,4,3,6,9,2,4,2,5,8,5,7,7,1,4,3,2,7,8,9,9,3,3,5,7,7,9,9,2,3,4,3,4,3,4,3,6};

    int id = 0;
#pragma omp parallel for num_threads(4)
    for(unsigned int i=0; i<vec_ids.size(); i++)
    {
        int threadnum = omp_get_thread_num();
        int numthreads = omp_get_num_threads();
        id = vec_ids[i];
#pragma omp critical
        std::cout<<"thread :: "<<threadnum<<" , total num thread :: "<<numthreads<<" ---- accessing :: "<<id<<std::endl<<std::flush;
        auto itr = map_u_prt.find(id);
        if(itr == map_u_prt.end())
        {
            map_u_prt[id] = std::make_unique<test_class>(id, 1.0);
        }
        map_u_prt[id]->update(1.0);
    }

    for (const auto& it : map_u_prt)
    {
        std::cout<<"##### "<<std::endl;
        it.second->print();
    }

    std::cout<<"##### SUCCESSFUL ##### "<<std::endl;
    return 0;
}

但是当我运行代码时,我会遇到随机的段错误。我正在尝试了解为什么会这样。我有点明白为什么会发生这种情况(如果我错了,请纠正我),但不清楚如何解决此问题。

auto itr = map_u_prt.find(id);

在上一行中,地图中的搜索未同步。这意味着一个线程可以看到存在特定ID的条目,而另一个线程尚未完成指针的插入,因此前一个线程将获得空对象和段错误。

有没有办法解决这个问题?我可以将检查和插入放入关键区域,但是在一个大循环中(vec_ids中有100万个条目),这是一个瓶颈。

0 个答案:

没有答案