环境
初始设置(工作正常)
两个文件main.py
和numbamodule.py
main.py
这将产生2个进程来运行execute_numba
函数。
import time
from importlib import import_module
from multiprocessing import Process
def execute_numba(name):
# Import the function
importfunction = 'numbamodule.numba_function'
module = import_module(importfunction.split('.')[0])
function = getattr(module, importfunction.split('.')[-1])
while True:
print(str(name) + ' - executing Numba function...')
# Execute the function
function(10)
time.sleep(0.1)
if __name__ == '__main__':
processes = [Process(target=execute_numba, args=(i,)) for i in range(2)]
[p.start() for p in processes]
time.sleep(1)
[p.terminate() for p in processes]
numbamodule.py
它定义了一个简单的函数numba_function
import numba
@numba.jit()
def numba_function(x):
total = 0
for i in range(x):
total += i
return total
我可以运行main.py
脚本,并看到两个进程都在打印:
$ python main.py
0 - executing Numba function...
1 - executing Numba function...
0 - executing Numba function...
1 - executing Numba function...
0 - executing Numba function...
1 - executing Numba function...
[...]
打破它
我打破它的方式有点奇怪,但这是我在试图最小化可重现的测试用例时偶然发现的。请告诉我,你是否也能重现同样的行为。
在main.py
中,我只需在最后一个Process
导入之后添加一个建议的(如下所示)导入(即:取消一行注释并尝试):
import time
from importlib import import_module
from multiprocessing import Process
#
# Adding one of the import lines bellow results in a block...
# (you may need to install the packages first in the virtual environment)
#
#import matplotlib
#import Pyro4
#import scipy
#import dill
def execute_numba(name):
# [...]
则一个进程可能在execute_numba
函数处阻塞(特别是在import_module()
调用处):
$ python main.py
1 - executing Numba function...
1 - executing Numba function...
1 - executing Numba function...
1 - executing Numba function...
1 - executing Numba function...
1 - executing Numba function...
[...]
对我来说,matplotlib
和Pyro4
导入“工作”最好。我甚至不能让区块100%的跑动...:-/
请注意,我只是添加了一个导入行,而不是实际使用的包。其他一些外部导入也会导致块,但我发现上面提出的那些“工作”最好(块最多)。
这是怎么回事?
首先,你能重现同样的行为吗?(对非虚拟化GNU/Linux机器特别感兴趣)
我不知道如何调试它,也不知道为什么会发生这种情况。有什么想法吗?
事实上,添加一个随机的import xxx
触发了这个块,这让我感到害怕,对我来说意义不大。这是否依赖于时间/延迟,这就是为什么一些导入会破坏它,而另一些则不会。
备注
numbamodule.py
中删除了import numba
和@numba.jit
,那么它总是可以工作的,所以也许它和Numba有关?
更新
import_module()
call.中
发布于 2018-05-13 21:02:56
这似乎是一个Numba bug,在issue 2431中得到了承认。
现在好像已经修好了。如果遇到这种情况,请更新您的numba
和llvmlite
安装。如果这不能解决问题,您可能应该在该问题中添加注释以重新打开它。
@stuartarchibald评论道:
...看起来有一个进程被阻塞是因为它实际上有分段故障...从这个位置出现的段错误几乎总是由于线程在LLVM中执行并发操作,或者在Numba初始化序列期间安装函数的一些问题造成的。..。无法再使用
llvmlite==0.22.0dev0
和numba==0.37.0.dev
进行复制...
发布于 2017-07-08 10:50:51
这只适用于matplotlib调试,实际上是猜测,但可能会帮助您缩小问题的范围。
当包含matplotlib时,您可以使用以下命令启动程序:
python main.py --verbose-helpful
它显示了matplotlib初始化时的调试输出。由于它听起来像是只存在于您的特定系统上的问题,因此matplotlibrc可能存在一些配置问题,其配置方式使其以交互模式启动。
下面是对可用的调试模式的概述:https://matplotlib.org/users/customizing.html
发布于 2017-07-03 08:48:00
下面是Python Docker官方环境的重现。Dockerfile
紧随其后(将您的.py
文件放在一起)。
FROM python:3.5
RUN pip install numba matplotlib pyro4
ADD . /opt
WORKDIR /opt
CMD python main.py
然后:
docker build -t so-44764520 .
docker run --rm -it so-44764520
两者都以相同的方式工作,没有“工作”的导入,matplotlib
和Pyro4
,并在main.py
中使用它们。
https://stackoverflow.com/questions/44764520
复制