如何使用 openMP 使此代码线程安全
How to make this code thread safe with openMP?
如果我删除#pragma omp parallel for
,下面显示的原理图代码可以正常工作,但是有了这个代码,代码就可以编译,但是在执行二进制文件时,我得到*** glibc detected *** ./testBin: double free or corruption (!prev): 0x0c43d8d8 ***
和core dumped
之类的错误。我猜原因是多个线程尝试写入变量omega, ell, ....
或lineVec
.我该如何解决这个问题?有没有办法告诉它变量是共享的?或者通常只有另一种并行执行此循环的方法。我对'openmp完全陌生,这是我第一次使用它。
#include <omp.h>
int main( int argc , char **argv )
{
vector <vector<string>> fileVec;
//some code that reads in a CSV file lines into elements of fileVec
//variables constituting a line:
//my_float has been typedef to be a high precision class in real code
my_float omega;
my_float ell;
my_float init1Real;
my_float init1Imag;
my_float dinit1Real;
my_float dinit1Imag;
my_float init2Real;
my_float init2Imag;
my_float dinit2Real;
my_float dinit2Imag;
#pragma omp parallel for private(lineVec,fileVec,ell,omega,init1Real,init1Imag,dinit1Real,dinit1Imag,init2Real,init2Imag,dinit2Real,dinit2Imag)
for (size_t i=0; i< fileVec.size(); i++)
{
lineVec=fileVec[i];
ell=lineVec[0];
omega=lineVec[1];
init1Real=lineVec[2];
init1Imag=lineVec[3];
dinit1Real=lineVec[4];
dinit1Imag=lineVec[5];
init2Real=lineVec[6];
init2Imag=lineVec[7];
dinit2Real=lineVec[8];
dinit2Imag=lineVec[9];
// cout<<"OUTPUT ell=" << ell<< " omega=" << omega <<" init1Real="<<init1Real<<endl;
//do some other calc involving these variables
}
}
从共享fileVec
读取是线程安全的。只有 my_float
类型的变量应该做得private
甚至更好 - 在循环中声明:
int main(int argc, char **argv)
{
vector<vector<string>> fileVec;
//some code that reads in a CSV file lines into elements of fileVec
#pragma omp parallel for private(lineVec)
for (size_t i = 0; i < fileVec.size(); i++)
{
lineVec = fileVec[i];
//my_float has been typedef to be a high precision class in real code
my_float ell = lineVec[0];
my_float omega = lineVec[1];
my_float init1Real = lineVec[2];
my_float init1Imag = lineVec[3];
my_float dinit1Real = lineVec[4];
my_float dinit1Imag = lineVec[5];
my_float init2Real = lineVec[6];
my_float init2Imag = lineVec[7];
my_float dinit2Real = lineVec[8];
my_float dinit2Imag = lineVec[9];
cout << "OUTPUT ell=" << ell << " omega=" << omega
<< " init1Real=" << init1Real << endl;
//do some other calc involving these variables
}
}
我在这里看不到任何比赛,除非my_float
不是线程安全的,或者//do some other calc involving these variables
中隐藏着其他东西.
请注意,对于最新的 OpenMP 版本,您甚至可以使用迭代器来遍历向量,因为它提供了一个随机访问迭代器:
typedef vector<vector<string>>::const_iterator iterType;
#pragma omp parallel for private(lineVec)
for (iterType it = lineVec.begin(); it != lineVec.end(); it++)
{
...
}
按照你编写它的方式,openmp 将创建一些线程并将 for 循环的迭代总数划分到每个线程之间。通过这样做,它将尝试对不同线程共享的向量执行并行读取。您可以更改数据共享属性(请参阅 OpenMP Wiki 有关数据共享属性子句的信息,在此 Microsoft 文档中,您有一个很好的示例。例如,要将 lineVec 和 fileVec 声明为"私有"使用:
#pragma omp parallel private(lineVec, fileVec)
此外,cout 不是线程安全的,从多个线程调用 cout 也需要序列化。
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- ASIO signal_set多个 IO 线程不可靠,具体取决于代码顺序?
- 如何分析代码的哪一部分创建了线程?
- 如何完全关闭 TBB 代码中的线程
- 提供对不同类型的数据(建议、代码审查)的线程安全访问的类
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- C++11:具有互斥锁的线程看到原子变量的值发生变化,尽管这是唯一可以改变它的代码
- 琐碎并发代码的吞吐量不会随着线程数量的增加而增加
- 删除原子多线程代码中的容器
- Visual Studio 发布模式阻止在调试模式下执行的代码.使用 WinHTTP 和多线程
- 开始多线程代码之前的初始化
- 使用 std::chrono::steady_clock 对线程/异步中的代码进行基准测试
- 实现在多线程代码中安全恢复的断点
- 一个简单的 win32 多线程代码.这能行吗?
- 终止调用本机代码的 .Net 线程
- 线程 1:xcode 中出现EXC_BAD_ACCESS(代码 = 1,地址 = 0x0)错误
- 有没有更好的方法可以使此代码线程安全?线程局部静态似乎是一个生硬的工具
- 如何使用 openMP 使此代码线程安全
- ls 此代码线程安全
- 如何使这个代码线程安全?ID + +;Print_Value (ID);