冻结脚本中的多处理python

时间:2019-03-23 00:25:19

标签: python python-3.x windows multiprocessing cx-freeze

我正在尝试使用multiprocessing将脚本编译为Windows可执行文件。起初,我在将Why python executable opens new window instance when function by multiprocessing module is called on windows编译成可执行文件时遇到了同样的问题。按照接受的答案,我将脚本调整为

from multiprocessing import freeze_support
# my functions
if __name__ == "__main__":
    freeze_support()
    # my script

当作为脚本运行时,这再次完美工作。但是,当我编译并运行它时,会遇到:

Error message

我在错误的绿色部分加了下划线。此特定行是指

freeze_support()

在我的脚本中。此外,在这一行上实际上并没有遇到它,但是当我的脚本进入多进程时,它是这样的:

p = multiprocessing.Process(target=my_function, args=[my_list])
p.start()
p1 = multiprocessing.Process(target=my_function, args=[my_list])
p1.start()
p.join()
p1.join()

这是多处理模块中的错误(特别是第148行),还是我误解了所链接的答案,还是其他原因?

我还将注意到该脚本在编译时可以正常工作,但是对于产生的每个多进程(很多),您必须在错误消息上单击“确定”,并且每个错误消息都完全相同。这是否意味着我会以p.join()不当地结束该过程?

我还在Python 3.4 multiprocessing does not work with py2exe尝试了解决方案,建议添加

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

您的脚本,但这会导致以下脚本形式的错误(甚至尚未编译):

  

FileNotFoundError:[WinError 2]系统找不到指定的文件

感谢您的帮助!

freeze_support文档:https://docs.python.org/2/library/multiprocessing.html#multiprocessing.freeze_support

2 个答案:

答案 0 :(得分:5)

这在相当长一段时间以来似乎一直是个问题-我发现至少可以追溯到2014年。由于它似乎是无害的,因此一般建议通过使用虚拟变量替换sys.stdout(和sys.stderr,并在下一行刷新)来抑制该错误。试试这个:

import os
import sys
from multiprocessing import freeze_support

if __name__ == '__main__':
    if sys.stdout is None:
        sys.stdout = sys.stderr = open(os.devnull, 'w')
    freeze_support()

答案 1 :(得分:2)

这不是多处理库或py2exe本身的问题,而是运行应用程序的方式的副作用。 py2exe documentation包含有关此主题的一些讨论:

  

在Windows下运行的程序可以有两种类型:控制台   程序或Windows程序。控制台程序是在其中运行的程序   命令提示符窗口(cmd)。控制台程序与用户互动   使用三个标准通道:标准输入,标准输出和   标准错误[…]。

     

与控制台应用程序相反,Windows应用程序进行交互   用户使用复杂的事件驱动的用户界面,并且   因此,不需要在此类应用中使用的标准频道   应用程序通常会导致崩溃。

Py2exe在某些情况下会自动解决这些问题,但是您的进程中至少有一个没有附加的标准输出:sys.stdoutNone),这意味着sys.stdout.flush()是{ {1}},它会产生您得到的错误。上面链接的文档有一个简单的修复程序,可以将所有输出重定向到文件。

None.flush()

只需在流程的入口点添加这些行。 interactions between Py2Exe and subprocesses上还有一个相关的文档页面。