2

Is it possible to destroy the threads created by OpenMP? When the program starts, there is only the one thread. After the parallelized section multiple threads remain since there is a thread pool. Is there any way to destroy this pool after the parallel section is run?

I ask because I'm using OpenMP in a dynamic library, and the library handle cannot be closed while the threads are running (the program will segfault).

Thanks

More explanation: I'm putting all parallelization code into modules (shared libraries). I then load the module and pass it a class derived from an abstract base class. The module then 'runs' that class in parallel. This way, I can use no parallelization, OpenMP, MPI, or anything else and can change the parallel scheme at run time or even on the fly. But OpenMP doesn't destroy the threads, and when it comes time to manually dlclose the library, it will segfault since the resources are destroyed from underneath the thread (I believe). Letting the program finish without closing the library is probably ok for now, but wanting to manually close the library may still come up in the future (think changing scheme on the fly). Hope this makes sense :) Thanks

Benjamin Pritchard
  • 915
  • 2
  • 8
  • 15

1 Answers1

3

At this point in time, the OpenMP specification doesn't give the user any ability to control when threads are destroyed. What you are saying is very interesting and hasn't been brought up during any of the OpenMP language committee meetings to discuss the specification. Can you give more information about what you are doing and what the problem is? It would be helpful in bringing this discussion to the committee.

Edit added 3/7 -

Okay - here is a simple example that seems to work and it might get around your problem:

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

While there is no OpenMP code in the main program (prog.c), I compiled it using the -fopenmp flag. This means that the OpenMP environment will be set up before the call to the shared library that is actually using OpenMP. This seems to get around the problem with doing a dlclose, since the environment is still there. It also allows the threads gotten by the first use of OpenMP to stay around for subsequent use. Does this work for getting around your problem (or does this only work for this simple example)?

ejd
  • 1,717
  • 1
  • 11
  • 10
  • Yeah looking around I didn't see any way at all - just that OpenMP automatically handles creation/destruction. I've appended my question with more information for you to peruse. :) BP – Benjamin Pritchard Mar 05 '11 at 03:46
  • Thank you for the explanation. Up to now, it has not been considered a problem to leave the library open until the program finishes. I think you are correct though, and this can be a problem and the committee should consider some way to shut OpenMP down. – ejd Mar 07 '11 at 15:17
  • After investigating a little while, I think the problem is actually in GDB. The main program is threading agnostic, but seems to work on its own. Under GDB (having to preload libpthread) it crashes. I tried your suggestion and linked the main program to OpenMP and now it indeed works under GDB. So maybe it was a bit rash to blame OpenMP; it's possible that GDB's handling of libraries is really to blame. Thanks for your input :) BP – Benjamin Pritchard Mar 10 '11 at 20:09
  • I've been discussing these issues in the OpenMP interop working group for a year or so... – Jeff Hammond Feb 12 '15 at 23:26
  • A better workaround would be to manually increase the refcount on the openmp shared library (you can get the .so handle from a function pointer). It is relevant for applications which support some sort of plugin architecture where you don't know if openmp is going to be used and you do not want openmp environment up just in case. – Sergey Sep 14 '15 at 02:18
  • So @Jeff - how are you discussions withe the OpenMP working group going? For context, this seems to be the same issue: https://github.com/Imagick/imagick/issues/295 – Danack Jul 25 '19 at 18:56
  • See omp_pause_resource in https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5.0.pdf :-) – Jeff Hammond Jul 25 '19 at 19:00
  • Thanks @Jeff, also thanks for answering slightly quicker than I was expecting. – Danack Jul 25 '19 at 19:29