使用cython的dask或joblib多重处理编译可执行文件会导致错误

发布于 2021-01-29 15:00:33

我正在将一些串行处理的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像导入一样,因此每个工人都尝试以递归方式启动五个新对象。

关注者
0
被浏览
87
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我认为,根据提交的错误报告中的详细信息,我可以在此处提供最优雅的解决方案

    if __name__ == '__main__':
        if sys.argv[0][-4:] == '.exe':
            setattr(sys, 'frozen', True)
        multiprocessing.freeze_support()
        YOURMAINROUTINE()
    

    freeze_support()需要-call在Windows上-
    看到蟒蛇多处理文档
    如果仅在该行中在python中运行,则已经可以了。
    但不知何故,用Cython显然是不知道的一些这些东西(的文档告诉它与测试py2exePyInstallercx_Freeze)。它可以通过setattr-call缓解,该调用仅在编译时使用,因此由文件扩展名决定。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看