【问题标题】:Destroying threads in Openmp (C++)在 Openmp (C++) 中销毁线程
【发布时间】:2011-03-04 23:28:00
【问题描述】:

是否可以销毁 OpenMP 创建的线程?程序启动时,只有一个线程。在并行化部分之后,由于存在线程池,因此保留了多个线程。并行部分运行后有什么方法可以销毁这个池?

我问是因为我在动态库中使用 OpenMP,并且在线程运行时无法关闭库句柄(程序会出现段错误)。

谢谢

更多解释: 我将所有并行化代码放入模块(共享库)中。然后我加载模块并将一个派生自抽象基类的类传递给它。然后该模块并行“运行”该类。这样,我可以不使用并行化、OpenMP、MPI 或其他任何东西,并且可以在运行时甚至动态更改并行方案。但是 OpenMP 不会破坏线程,当需要手动 dlclose 库时,它会出现段错误,因为资源是从线程下面破坏的(我相信)。让程序在不关闭库的情况下完成现在可能还可以,但是将来可能仍然会出现想要手动关闭库的想法(考虑即时更改方案)。希望这是有道理的:) 谢谢

【问题讨论】:

    标签: c++ multithreading openmp dynamic-library


    【解决方案1】:

    此时,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 获得的线程保留以供后续使用。这是否可以解决您的问题(或者这仅适用于这个简单的示例)?

    【讨论】:

    • 是的,环顾四周,我根本没有看到任何方法——只是 OpenMP 会自动处理创建/销毁。我已在我的问题中附加了更多信息供您阅读。 :) BP
    • 感谢您的解释。到目前为止,在程序完成之前让库保持打开状态并不被认为是一个问题。不过我认为你是对的,这可能是个问题,委员会应该考虑一些方法来关闭 OpenMP。
    • 调查了一会儿,我认为问题实际上出在GDB上。主程序与线程无关,但似乎可以独立工作。在 GDB 下(必须预加载 libpthread)它会崩溃。我尝试了您的建议并将主程序链接到 OpenMP,现在它确实可以在 GDB 下运行。所以也许责怪 OpenMP 有点轻率。 GDB 对库的处理可能真的是罪魁祸首。感谢您的意见:) BP
    • 我在 OpenMP 互操作工作组中讨论这些问题已经有一年左右的时间了...
    • 更好的解决方法是手动增加 openmp 共享库的引用计数(您可以从函数指针获取 .so 句柄)。它与支持某种插件架构的应用程序相关,您不知道是否要使用 openmp 并且您不希望打开 openmp 环境以防万一。
    猜你喜欢
    • 2020-11-07
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    相关资源
    最近更新 更多