Уничтожение потоков в Openmp (C ++) - PullRequest
2 голосов
/ 05 марта 2011

Можно ли уничтожить потоки, созданные OpenMP?Когда программа запускается, есть только один поток.После распараллеленной секции остается несколько потоков, поскольку существует пул потоков.Есть ли способ уничтожить этот пул после запуска параллельного раздела?

Я спрашиваю, потому что я использую OpenMP в динамической библиотеке, и дескриптор библиотеки не может быть закрыт во время работы потоков (программа будетsegfault).

Спасибо

Дополнительные пояснения: Я помещаю весь код распараллеливания в модули (разделяемые библиотеки).Затем я загружаю модуль и передаю ему класс, производный от абстрактного базового класса.Затем модуль «запускает» этот класс параллельно.Таким образом, я не могу использовать распараллеливание, OpenMP, MPI или что-либо еще и могу изменить параллельную схему во время выполнения или даже на лету.Но OpenMP не уничтожает потоки, и когда приходит время закрывать библиотеку вручную, он вызывает ошибку, поскольку ресурсы уничтожаются из-под потока (я полагаю).Позволить программе завершиться, не закрывая библиотеку, вероятно, пока нормально, но желание вручную закрыть библиотеку может все еще возникнуть в будущем (подумайте об изменении схемы на лету).Надеюсь, что это имеет смысл :) Спасибо

1 Ответ

3 голосов
/ 05 марта 2011

На данный момент спецификация OpenMP не дает пользователю никакой возможности контролировать, когда потоки уничтожаются. То, что вы говорите, очень интересно и не обсуждалось ни на одном из заседаний языкового комитета OpenMP для обсуждения спецификации. Можете ли вы дать больше информации о том, что вы делаете и в чем проблема? Было бы полезно довести эту дискуссию до комитета.

Редактировать добавлено 3/7 -

Хорошо - вот простой пример, который, кажется, работает и может обойти вашу проблему:

$> 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

Хотя в основной программе (prog.c) нет кода OpenMP, я скомпилировал его с помощью флага -fopenmp. Это означает, что среда OpenMP будет настроена до вызова общей библиотеки, которая фактически использует OpenMP. Это, кажется, обходит проблему с выполнением dlclose, так как среда все еще там. Это также позволяет потокам, полученным при первом использовании OpenMP, оставаться на месте для последующего использования. Это работает для решения вашей проблемы (или это работает только для этого простого примера)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...