我正在尝试遍历包含唯一指针作为值的映射。这是实现。代码可以编译,没问题。
#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万个条目),这是一个瓶颈。