Python 3.4 多处理不适用于 py2exe

Posted

技术标签:

【中文标题】Python 3.4 多处理不适用于 py2exe【英文标题】:Python 3.4 multiprocessing does not work with py2exe 【发布时间】:2015-03-18 06:23:48 【问题描述】:

这与this question 几乎相同,但那里给定的解决方案(调用 freeze_support())对我不起作用。

我有以下名为 start.py 的脚本,我用它来构建带有 py2exe(版本 0.9.2.2)的独立可执行文件。我在同一目录中也有 python.exe。

import multiprocessing

def main():
    print('Parent')
    p = multiprocessing.Process(target=new_process)
    multiprocessing.set_executable('python.exe')
    p.start()
    p.join()

def new_process():
    print('Child')

if __name__ == '__main__':
    multiprocessing.freeze_support()
    main()

当作为纯 python 运行时,它工作得非常好。但是,当打包为可执行文件时,这是我得到的错误:

Unknown option: --
usage: <path to start.exe> [option] ... [-c cmd | -m mod | file | -] [arg] ...
Try `python -h' for more information.

这显然是调用造成的

python.exe --multiprocessing-fork

如果我不调用 set_executable() 和 freeze_support(),子进程只会启动 exe 并作为 __main__ 运行,从而导致无限的新进程链打印“父”,而永远不会打印“子”。

如果我不调用 multiprocessing.set_executable(),调用 freeze_support() 似乎唯一会导致子进程引发以下错误

Traceback (most recent call last):
  File "start.py", line 17, in <module>
    multiprocessing.freeze_support()
  File "C:\Python34\Lib\multiprocessing\context.py", line 148, in freeze_support

    freeze_support()
  File "C:\Python34\Lib\multiprocessing\spawn.py", line 67, in freeze_support
    main()
NameError: name 'main' is not defined

我正在使用在 Windows 8.1 64 位上运行的 Python 3.4 32 位。我已经使用 cx-Freeze 尝试了上述所有方法,结果相同。任何帮助将不胜感激。

编辑:即使使用此示例 straight out of the docs:

from multiprocessing import Process, freeze_support

def f():
    print('hello world!')

if __name__ == '__main__':
    freeze_support()
    Process(target=f).start()

当子进程调用 freeze_support() 时,我得到相同的 NameError。

【问题讨论】:

我的工具pynsist 可能有用。它不会使您的代码成为 exe,因此您不需要任何特殊技巧来使多处理工作。它构建了一个安装程序,用于设置 Python 本身以及您的代码。 我能够使用 Python 2.7.9 和 py2exe 0.6.9 让它工作,前提是我删除了对 set_executable 的调用,但仍然调用了 freeze_support()。我最好的猜测是 freeze_support() 在 Python 3 中无法正常运行。 【参考方案1】:

尝试建议的修复in the docs:

multiprocessing.set_executable(os.path.join(sys.exec_prefix, 'pythonw.exe'))

另请注意,您需要在生成任何新进程之前调用它。

【讨论】:

这给了我和我现在一样的结果。我尝试在初始化进程之前将 set_executable 移动到 if _name_ == '_main_' 在调用 freeze_support() 之前和之后都没有效果. 还有一点需要注意:sys.exec_prefix 在打包的可执行文件中实际上是一个空字符串。如果我没有在工作目录中包含 python.exe,我会收到 FileNotFoundError,因为多处理找不到 python.exe。 我遇到了这个确切的问题。而不是使用python.exe,您应该使用pythonw.exe,这似乎正在解决Unknown option: --

以上是关于Python 3.4 多处理不适用于 py2exe的主要内容,如果未能解决你的问题,请参考以下文章

多处理问题[pyqt,py2exe]

Python wave 模块仅适用于 v2.7,不适用于 v3.4 linux

从批处理脚本编写 Python 脚本不适用于一个命令

py2exe打包python脚本

time.sleep 不适用于多线程

如何在 extjs 3.4 中为 ajax 调用处理 windows auth 握手(401)?