我正在尝试使用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
当作为脚本运行时,这再次完美地运行。但是,当我编译并运行它时遇到:
我在错误的绿色部分加下划线。这个具体的行是指
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
这似乎是一个问题很长一段时间 - 我发现至少可以追溯到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()
这不是多处理库或py2exe本身的问题,而是运行应用程序的方式的副作用。 py2exe documentation包含有关此主题的一些讨论:
在Windows下运行的程序可以有两种类型:控制台程序或Windows程序。控制台程序是在命令提示符窗口(cmd)中运行的程序。控制台程序使用三个标准通道与用户交互:标准输入,标准输出和标准错误[...]。
与控制台应用程序相反,Windows应用程序使用复杂的事件驱动用户界面与用户交互,因此不需要在此类应用程序中使用的标准通道通常会导致崩溃。
在某些情况下,Py2exe会自动解决这些问题,但至少有一个进程没有附加的标准输出:sys.stdout
是None
),这意味着sys.stdout.flush()
是None.flush()
,它会产生你得到的错误。上面链接的文档有一个简单的修复方法,可以将所有输出重定向到文件。
import sys
sys.stdout = open(“my_stdout.log”, “w”)
sys.stderr = open(“my_stderr.log”, “w”)
只需在流程的入口点添加这些行。 interactions between Py2Exe and subprocesses上还有一个相关的文档页面。