python - 为什么当通过 swig 从子进程调用时,使用 OpenMP 的共享库中的函数会挂起?

标签 python c openmp python-multiprocessing swig

我正在尝试包装一个最小的 C 库,其中包含一个文件“locks.h”,其中包含

#ifndef LOCKS_H
#define LOCKS_H
void f(void);
#endif

和“locks.c”包含

#include <stdio.h>

void f(void) {
#pragma omp parallel
  {
    fprintf(stderr, "Hello World!\n");
  }
  return;
}

使用 swig,使用包含 swig 输入文件“locks.i”

%module locks

%{
#define SWIG_FILE_WITH_INIT
#include "locks.h"
%}

void f(void);

然后我使用

创建并构建包装器
swig -python locks.i
gcc -fPIC -shared -I/usr/include/python3.6/ -fopenmp locks.c locks_wrap.c -g -o _locks.so

以及快速测试

python3 -c "import locks; locks.f()"

似乎按预期工作。

但是,当我调用函数 f 两次时,一次从 python 主进程调用,一次从子进程调用,如下所示:

from multiprocessing import Process

import locks

locks.f()

print('Launching Process')
p = Process(target=locks.f)
p.start()
p.join()
print(p.exitcode)

代码在子进程的调用中挂起,仅打印

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Launching Process
Hello World!

在 Python 3.6 和

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Launching Process

在具有 4 核和 8 个超线程的 Intel CPU 上的 Python 3.8 中。

如果我只从子进程中调用该函数,而不是在两个进程中调用该函数,则子进程中的调用也会按预期成功。

目标系统是 64 位 Linux(本例中为 Ubuntu 18.04)。

我该如何解决这个问题?

最佳答案

正如 Zulan 所指出的在评论中,核心问题似乎是 one cannot call OpenMP functions after a fork .

幸运的是,Python 多处理允许您使用 set_start_method()函数来请求它不是 fork ,而是从头开始生成全新的解释器进程。

因此通过将 python 脚本调整为

import multiprocessing as mp

import locks

if __name__ == '__main__':
    mp.set_start_method('spawn')

    locks.f()

    print('Launching Process')
    p = mp.Process(target=locks.f)
    p.start()
    p.join()
    print(p.exitcode)

问题已解决。

关于python - 为什么当通过 swig 从子进程调用时,使用 OpenMP 的共享库中的函数会挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59251966/

相关文章:

iphone - sscanf 在 iPhone OS 3.1.2 上是线程安全的吗?

c++ - 在运行时设置 OMP_THREAD_LIMIT 的问题 (c++ gcc 4.4.7)

c - openMP 以及如何检查缓存行为并行性

python - 关闭 tkinter 窗口和消息框错误窗口

python - 用离散数据的水平绘制等值线

python - 将视频保存为帧 OpenCV{PY}

使用 OpenMP 时 for 循环在 if else 语句中时出现 C++ 错误

python - Tkinter 文本小部件间距

c - 24 小时时间格式正则表达式

c - 在递归中在其自己的声明中使用变量