Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么通过swig从子进程调用使用OpenMP的共享库中的函数时会挂起?_Python_C_Openmp_Python Multiprocessing_Swig - Fatal编程技术网

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

Python 为什么通过swig从子进程调用使用OpenMP的共享库中的函数时会挂起?,python,c,openmp,python-multiprocessing,swig,Python,C,Openmp,Python Multiprocessing,Swig,我试图包装一个最小的C库,它由一个文件“locks.h”组成,其中包含 %module locks %{ #define SWIG_FILE_WITH_INIT #include "locks.h" %} void f(void); \ifndef锁 #定义锁 无效f(无效); #恩迪夫 和“locks.c”包含 %module locks %{ #define SWIG_FILE_WITH_INIT #include "locks.h" %} void f(void); #包括

我试图包装一个最小的C库,它由一个文件“locks.h”组成,其中包含

%module locks

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

void f(void);
\ifndef锁
#定义锁
无效f(无效);
#恩迪夫
和“locks.c”包含

%module locks

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

void f(void);
#包括
无效f(无效){
#pragma-omp并行
{
fprintf(stderr,“你好,世界!\n”);
}
返回;
}
对于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主进程调用,一次从如下子进程调用:

来自多处理导入进程的

导入锁
locks.f()
打印('启动过程')
p=进程(目标=锁.f)
p、 开始()
p、 加入
打印(p.exitcode)
代码挂起在子流程中的调用中,仅打印

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Launching Process
Hello World!
在Python3.6和

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Launching Process
在Python 3.8中,在具有4个内核和8个超线程的Intel CPU上运行

如果我只从子流程调用函数,而不是在两个流程中都调用函数,那么子流程中的调用也会按预期成功

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

如何解决这个问题?

正如在一篇评论中所指出的,核心问题似乎是

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

因此,通过将python脚本调整为

将多处理导入为mp
导入锁
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
mp.set\u start\u方法('spawn')
locks.f()
打印('启动过程')
p=mp.Process(target=locks.f)
p、 开始()
p、 加入
打印(p.exitcode)
问题已经解决。

正如在评论中指出的,核心问题似乎是

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

因此,通过将python脚本调整为

将多处理导入为mp
导入锁
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
mp.set\u start\u方法('spawn')
locks.f()
打印('启动过程')
p=mp.Process(target=locks.f)
p、 开始()
p、 加入
打印(p.exitcode)

问题已解决。

什么目标系统?fprintf在Linux和Windows上应该是线程安全的,但不能保证其他(非POSIX)系统。@Lundin我使用的是Ubuntu 18.04 64位。很确定这就是本质上的问题:-这基本上意味着,你不能这样做(线程+子进程)@Zulan-Hm,看起来不错。那太不幸了。。。谢谢你的链接。什么目标系统?fprintf在Linux和Windows上应该是线程安全的,但不能保证其他(非POSIX)系统。@Lundin我使用的是Ubuntu 18.04 64位。很确定这就是本质上的问题:-这基本上意味着,你不能这样做(线程+子进程)@Zulan-Hm,看起来不错。那太不幸了。。。谢谢你的链接。