使用cython的dask或joblib多重处理编译可执行文件会导致错误
我正在将一些串行处理的python作业转换为dask或joblib的多处理程序。可悲的是我需要在Windows上工作。
从IPython内部运行或从命令行调用python的py文件时,一切运行良好。
使用cython编译可执行文件时,它不再能正常运行:越来越多的进程(无限且大于请求的进程数)逐步启动并阻塞我的系统。
感觉就像多处理炸弹一样-但我当然使用if __name__=="__main__:"
过控制块-通过在命令行上从python调用中正常运行来批准。
我的cython调用是的cython --embed --verbose --annotate THECODE.PY
,我正在编译以gcc -time
-municode -DMS_WIN64 -mthreads -Wall -O -I"PATH_TO_\include" -L"PATH_TO_\libs"
THECODE.c -lpython36 -o THECODE
生成Windows可执行文件THECODE.exe
。
与其他(单个处理)代码一起运行良好。
这个问题对于dask和joblib似乎是相同的(可能意味着dask的工作方式类似于Joblib或基于Joblib)。
有什么建议?
对于那些对mcve感兴趣的人:仅从Multiprocessing
Bomb中获取第一个代码,并使用上面的cython命令对其进行编译,将导致可执行文件崩溃。(我刚刚尝试过:-))
通过在代码示例中添加一行以显示,我发现了一些有趣的东西__name__
:
import multiprocessing
def worker():
"""worker function"""
print('Worker')
return
print("-->" + __name__ + "<--")
if __name__ == '__main__':
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker)
jobs.append(p)
p.start()
当运行这段代码python
时显示
__main__
__mp_main__
__mp_main__
__mp_main__
__mp_main__
__mp_main__
(其他输出被抑制)。说明if决策有效。在cython之后运行可执行文件并显示编译时
__main__
__main__
__main__
__main__
__main__
__main__
越来越多。因此,工人对模块的调用不再masqueraded
像导入一样,因此每个工人都尝试以递归方式启动五个新对象。
-
我认为,根据提交的错误报告中的详细信息,我可以在此处提供最优雅的解决方案
if __name__ == '__main__': if sys.argv[0][-4:] == '.exe': setattr(sys, 'frozen', True) multiprocessing.freeze_support() YOURMAINROUTINE()
在
freeze_support()
需要-call在Windows上-
看到蟒蛇多处理文档。
如果仅在该行中在python中运行,则已经可以了。
但不知何故,用Cython显然是不知道的一些这些东西(的文档告诉它与测试py2exe
,PyInstaller
和cx_Freeze
)。它可以通过setattr
-call缓解,该调用仅在编译时使用,因此由文件扩展名决定。