以下代码应该非常简单,但是当尝试在具有嵌套OpenMP代码的线程上执行.join()时,似乎最终处于悬空状态。使用GCC编译器4.7.2 x64和http://sourceforge.net/projects/mingwbuilds与g++ threadexample.cpp -Wall -std=c++11 -fopenmp -o threads
// threadexample.cpp
#include <iostream>
#include <thread>
#include <omp.h>
using namespace std;
void hello(int a) {
#pragma omp parallel for
for (int i=0;i<5;++i) {
#pragma omp critical
cout << "Hello from " << a << "! " << "OMP thread iter " << i << endl;
}
cout << "About to return from hello function" << endl;
}
int main (int argc, char ** argv) {
thread t1(hello, 1); //fork
cout << "t1 away!" << endl;
thread t2(hello, 2);
cout << "t2 away!" << endl;
t1.join(); //join
cout << "thread 1 joined" << endl;
t2.join();
cout << "thread 2 joined" << endl;
return 0;
}
答案 0 :(得分:7)
混合使用OpenMP和任何其他线程库(pthreads
,Win32线程等)可能不是一个好主意。可以编写OpenMP运行时,假设它完全控制线程,并且可能不支持并发运行parallel
区域(例如,它可能使用信号量等全局变量来控制线程池)。
实现这一目标的更好的纯OpenMP方法是:
#include <iostream>
#include <omp.h>
using namespace std;
void hello(int a) {
#pragma omp parallel for
for (int i=0;i<5;++i) {
#pragma omp critical
cout << "Hello from " << a << "! " << "OMP thread iter " << i << endl;
}
cout << "About to return from hello function" << endl;
}
int main (int argc, char ** argv) {
omp_set_nested(1);
#pragma omp parallel sections num_threads(2)
{
#pragma omp section
{
hello(1);
}
#pragma omp section
{
hello(2);
}
}
return 0;
}
需要调用omp_set_nested()
才能启用默认禁用的嵌套并行操作。