6

次のコードは非常に単純ですが、ネストされた OpenMP コードを含むスレッドで .join() を実行しようとすると、ハングアップするようです。http://sourceforge.net/projects/mingwbuildsの pthreads で GCC コンパイラ 4.7.2 x64 を使用する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;
}
4

1 に答える 1

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()が必要です。

于 2012-11-02T15:46:36.277 に答える