2011-03-04 4 views
2

OpenMP에서 만든 스레드를 파괴 할 수 있습니까? 프로그램이 시작되면 하나의 스레드 만 있습니다. 스레드 풀이 있기 때문에 병렬 처리 된 섹션이 여러 개 남아 있습니다. 병렬 섹션을 실행 한 후에이 풀을 파괴 할 수있는 방법이 있습니까?Openmp에서 스레드 삭제 (C++)

나는 동적 라이브러리에서 OpenMP를 사용하고 스레드가 실행되는 동안 라이브러리 핸들을 닫을 수 없기 때문에 질문합니다 (프로그램은 segfault입니다).

감사

더 설명 : 나는 모듈 (공유 라이브러리)에 모든 병렬 코드를 걸었습니다. 그런 다음 모듈을로드하고 추상 기본 클래스에서 파생 된 클래스를 전달합니다. 그런 다음 모듈은 해당 클래스를 병렬로 실행합니다. 이렇게하면 병렬화, OpenMP, MPI 또는 다른 어떤 것도 사용할 수 없으며 런타임에 또는 심지어 실행 중에도 병렬 구성표를 변경할 수 있습니다. 하지만 OpenMP는 스레드를 파괴하지 않으며, 라이브러리를 수동으로 dlclose 할 때가되면 스레드가 스레드 아래에서 리소스가 파괴되므로 segfault가 발생합니다 (필자는 믿습니다). 라이브러리를 닫지 않고 프로그램을 끝내는 것은 현재로서는 괜찮은 일이지만, 라이브러리를 수동으로 닫으려는 것은 앞으로도 계속 발생할 수 있습니다. 희망이 이해가 :) 감사합니다

답변

3

이 시점에서 OpenMP 사양은 스레드가 파괴되면 제어 할 수있는 능력을 사용자에게 부여하지 않습니다. 당신이 말하는 것은 매우 흥미롭고 OpenMP 언어위원회 중 하나에서 논의되지 않은 채로 제기 된 것이 아닙니다. 당신이하고있는 일과 그 문제에 대해 더 많은 정보를 줄 수 있습니까? 이 토론을위원회에 가져 오는 것이 도움이 될 것입니다. 더 OpenMP의 코드가에 없지만

$> cat prog.c 
#include <stdio.h> 
#include <stdlib.h> 
#include <dlfcn.h> 

int main(void) 
{ 
    void (*f)(void); 
    void *handle; 

    handle = dlopen("./shared.so", RTLD_NOW); 
    if (!handle) { 
    printf("*** dlopen error - %s\n", dlerror()); 
    abort(); 
    } 

    f = dlsym(handle, "foo"); 
    if (!f) { 
    printf("*** dlsym error - %s\n", dlerror()); 
    abort(); 
    } 
    f(); 

    if(dlclose(handle)) { 
    printf("*** dlclose error - %s\n", dlerror()); 
    abort(); 
    } 
    return 0; 
} 

$> cat shared.c 
#include <omp.h> 
#include <stdio.h> 

void foo(void) 
{ 
    int i; 

    puts("... in foo\n"); 

    #pragma omp parallel for 
    for (i=0; i<10; i++) 
    printf("t#: %i i: %i\n", omp_get_thread_num(), i); 

    puts("... exiting foo"); 
} 

$> gcc -rdynamic -fopenmp prog.c -ldl -o prog                 
$> gcc -c -fopenmp -fPIC -o shared.o shared.c                 
$> ld -shared -o shared.so shared.o                   
$> ./prog 
... in foo 

t#: 2 i: 4 
t#: 2 i: 5 
t#: 3 i: 6 
t#: 3 i: 7 
t#: 0 i: 0 
t#: 0 i: 1 
t#: 4 i: 8 
t#: 4 i: 9 
t#: 1 i: 2 
t#: 1 i: 3 
... exiting foo 

: -

좋아 - 여기에 작동하는 것 같다 간단한 예제이며, 그것은 당신의 문제를 해결 얻을 수 있습니다

편집 3/7를 추가 주 프로그램 (prog.c)에서 -fopenmp 플래그를 사용하여 컴파일했습니다. 즉, 실제로 OpenMP를 사용하는 공유 라이브러리를 호출하기 전에 OpenMP 환경이 설정됩니다. 이것은 환경이 여전히 존재하기 때문에 dlclose를 수행하면서 문제를 해결하는 것 같습니다. 또한 OpenMP를 처음 사용할 때 얻은 스레드를 이후 사용을 위해 머무를 수 있습니다. 문제를 해결하기 위해이 방법이 효과가 있습니까? (또는이 간단한 예제에서만 작동합니까?)

+0

주위를 둘러 보았습니다. 전혀 볼 방법이 없었습니다. OpenMP가 자동으로 생성/삭제를 처리한다는 것입니다. 나는 너를 위해 정독 할 더 많은 정보를 담은 나의 질문을 덧붙였다. :) BP –

+0

설명해 주셔서 감사합니다. 지금까지는 프로그램이 끝날 때까지 도서관을 열어 두는 것이 문제로 여겨지지 않았습니다. 나는 당신이 정확하다고 생각합니다, 그리고 이것이 문제가 될 수 있으며,위원회는 OpenMP를 종료하는 방법을 고려해야합니다. – ejd

+0

조금만 조사한 후에 문제가 실제로 GDB에 있다고 생각합니다. 메인 프로그램은 불가지론 스레딩이지만, 독자적으로 작동하는 것처럼 보입니다. GDB (libpthread를 미리로드해야 함)에서 충돌이 발생합니다. 나는 당신의 제안을 시도하고 메인 프로그램을 OpenMP에 연결 시켰으며, 이제 GDB 하에서 실제로 작동합니다. 그래서 아마도 OpenMP를 비난하는 것은 다소 성급한 것이 었습니다. GDB의 라이브러리 처리가 실제로 비난받을 가능성이 있습니다. 귀하의 의견을 주셔서 감사합니다 : BP –