我有一个 C++ 程序,我尝试在 for 循环中使用 openmp。 for 循环与我自己的类的 shared_ptr 一起工作,该类又调用另一个 dll。我收到错误:
Table 7. Current pointer and in_use_count are inconsistent.
代码看起来像这样..
int n = 1000;
std::vector<double> result(n),indata(n);
// populate indata
std::shared_ptr<MyNS::MyClass> sp_mycl = std::make_shared < MyNS::MyClass >();
sp_mycl->var1 = 2;
// populate sp_mycl->v_var4
#pragma omp parallel for firstprivate(sp_mycl)
for (auto ii = 0; ii<n;ii++)
{
sp_mycl->var2 = indata[ii];
sp_mycl->calc();
result[ii] = sp_mycl->var3;
}
MyClass.h 与此类似
namespace MyNS
{
extern "C" { double * fortran_dll_calc(int *num, double arrinput[],double arroutput[])} // subroutine in fortran dll
class MyClass
{
double var1, var2, var3;
std::vector<double> v_var4;
void calc();
}
}
和 MyClass.cpp
using namespace MyNS;
void MyClass::calc()
{
int len = v_var4.size();
double *test = new double[len];
for (auto is = 0; is<len;is++)
test[is] = v_var4[is];
double fortran_result[10]; // output from fortran dll
fortran_dll_calc(len,test,fortran_result);
for (int ir = 0;ir < 10;ir++)
var3 += fortran_result[ir];
}
我将 MSVS 与 Intel parallel studio c++/fortran 编译器 2016 结合使用。
我希望 sp_mycl->var1
对所有线程具有相同的初始值,因此 sp_mycl
的 firstprivate。
openmp for 循环似乎在某处出错了,在调试时它有时似乎在 MyClass::calc()
中停止,有时已经在 sp_mycl->var2= indata [ii]
。这是我使用一些 cout
输出发现的。
firstprivate
是否与 shared_ptr
一起用于我自己定义的对象?
我是初学者,因此可能会有很多错误和错误,欢迎对代码中的任何内容发表评论。
最佳答案
OpenMP 将为每个线程初始化私有(private)版本的 sp_mycl
,如下所示:
auto priv_sp_mycl = sp_mycl;
这是并行完成的,并调用复制构造函数,它最终需要更新 shared_ptr
的引用计数。但是,STL 中的 shared_ptr
实现不是线程安全的,因此事情开始出错。
但是,我不确定这是否是您想要的。为什么要让每个线程都指向同一个对象?这不会在您的程序中引入额外的竞争条件吗?此外,每个线程都将结果写入 result[n]
...您是说 result[ii]
吗?
无论如何,我认为这就是您想要的:
MyNS::MyClass sp_mycl;
sp_mycl.var1 = 2;
// populate sp_mycl->v_var4
#pragma omp parallel for firstprivate(sp_mycl)
for (auto ii = 0; ii<n;ii++)
{
sp_mycl.var2 = indata[ii];
sp_mycl.calc();
result[ii] = sp_mycl.var3;
}
关于由 小码哥发布于 2019-03-18 标签:c++openmpshared_ptrdatarace,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33963541/