为什么我在使用 OpenMP 的共享库中的函数在通过 swig 从子进程调用时挂起?
Why does my function in a shared library which uses OpenMP hang when called from a subprocess via 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;
}
with 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
在 Python 3.8 中,Intel CPU 具有 4 个内核和 8 个超线程。
如果我只从子进程中调用函数,而不是在两个进程中调用,那么子进程中的调用也会按预期成功。
目标系统是 64 位 Linux(本例中为 Ubuntu 18.04)。
我该如何解决这个问题?
正如Zulan in a comment, the core issue appears to be that 所指出的那样。
幸运的是,Python 多处理允许您使用 set_start_method()
函数请求它从头开始生成全新的解释器进程,而不是分叉。
因此,通过将 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)
问题已解决。
我正在尝试包装一个最小的 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;
}
with 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
在 Python 3.8 中,Intel CPU 具有 4 个内核和 8 个超线程。
如果我只从子进程中调用函数,而不是在两个进程中调用,那么子进程中的调用也会按预期成功。
目标系统是 64 位 Linux(本例中为 Ubuntu 18.04)。
我该如何解决这个问题?
正如Zulan in a comment, the core issue appears to be that
幸运的是,Python 多处理允许您使用 set_start_method()
函数请求它从头开始生成全新的解释器进程,而不是分叉。
因此,通过将 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)
问题已解决。