本文介绍了为什么当使用嵌套的OpenMP pragmas时,c ++ 11线程不可连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码应该很简单,但似乎最终在一个悬挂的情况下,试图在嵌套OpenMP代码的线程上做一个.join()。使用来自的带有pthread的GCC编译器4.7.2 x64与 g ++ threadexample.cpp -Wall -std = c ++ 11 -fopenmp -o threads

The following code should be pretty straightforward but seems to end up in a hanging situation when trying to do a .join() on the threads with nested OpenMP code. Using GCC compiler 4.7.2 x64 with pthreads from http://sourceforge.net/projects/mingwbuilds with 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;
}


推荐答案

混合OpenMP和任何其他线程库( pthreads ,Win32线程等)可能不是一个好主意。 OpenMP运行时可能假定它完全控制线程,并且可能不支持并行运行的区域(例如它可能使用全局变量,如信号量

Mixing OpenMP and any other threading library (pthreads, Win32 threading, etc.) might not be a good idea. The OpenMP run-time might be written with the presumption that it is fully in control of threading and might not support parallel regions being run concurrently (e.g. it might use global variables like semaphores to control the thread pools).

更好的纯粹的OpenMP方法是:

A better pure OpenMP way to implement this would be:

#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()是为了启用默认禁用的嵌套并行性。

The call to omp_set_nested() is needed in order to enable nested parallelism which is disabled by default.

这篇关于为什么当使用嵌套的OpenMP pragmas时,c ++ 11线程不可连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 06:43