为啥在windows上调用多处理模块的函数时python可执行文件会打开新的窗口实例

Posted

技术标签:

【中文标题】为啥在windows上调用多处理模块的函数时python可执行文件会打开新的窗口实例【英文标题】:Why python executable opens new window instance when function by multiprocessing module is called on windows为什么在windows上调用多处理模块的函数时python可执行文件会打开新的窗口实例 【发布时间】:2016-03-02 10:35:27 【问题描述】:

小问题:为什么在windows操作系统上调用多处理模块的函数时,pyinstaller生成的python可执行文件会打开新的窗口实例

我有一个使用 pyside 编写的 GUI 代码。当我们点击简单按钮时,它将在另一个进程中计算阶乘(使用多处理模块)。 当我运行 python 程序时,它按预期工作。但是在我使用 PyInstaller 创建可执行文件之后,当我使用 exe 运行时,它会在调用多处理模块的函数时创建新窗口。这是重现问题的代码和分步过程。

代码:

import sys
import multiprocessing

from PySide import QtGui
from PySide import QtCore


def factorial():
        f = 4
        r = 1
        for i in reversed(range(1, f+1)):
            r *= i 
        print 'factorial', r


class MainGui(QtGui.QWidget):
    def __init__(self):
        super(MainGui, self).__init__()

        self.initGui()

    def initGui(self):
        b = QtGui.QPushButton('click', self)
        b.move(30, 30)
        b.clicked.connect(self.onClick)
        self.resize(600, 400)
        self.show()

    def onClick(self):
        print 'button clicked'
        self.forkProcess()

    def forkProcess(self):
        p = multiprocessing.Process(target=factorial)
        p.daemon = True
        p.start()



if __name__ == "__main__":
    print 'ok'

    app = QtGui.QApplication(sys.argv)
    ex = MainGui()
    sys.exit(app.exec_())

    使用 windows 命令提示符或 power shell 运行上述代码

    pyinstaller.exe gui.py

    打开 dist/gui/gui.exe (dist\gui\gui.exe)。您将打开一个窗口

当我们点击按钮 click 时,它正在计算阶乘,但会创建一个新的窗口实例。有点奇怪。在创建可执行文件之前或在 linux 上执行程序时不会发生这种情况。只有当我执行生成的 python 可执行文件时才会发生这种情况

我点击点击按钮后的屏幕截图

【问题讨论】:

Windows 不支持fork()。新进程通过CreateProcess 生成。使用 python.exe 它可以使用-c 命令行脚本调用multiprocessing.forking.main。对于冻结的可执行文件,您应该立即致电freeze_support 【参考方案1】:

如果您想将多处理用作冻结的可执行文件,您需要在主脚本的开头调用multiprocessing.freeze_support()。这将允许多处理在产生其工作进程时“接管”。

另见https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing

【讨论】:

以上是关于为啥在windows上调用多处理模块的函数时python可执行文件会打开新的窗口实例的主要内容,如果未能解决你的问题,请参考以下文章

为啥在windows上使用python多处理时打印三遍?

为啥我使用多处理/多线程的函数在 for 循环中使用时如此缓慢,但在循环之外却没有?

为啥windows在调用函数时需要大小?

multiprocessing

在windows系统中对套接字数据进行io时为啥不可以直接使用文件io相关函数?

python-多线程:调用thread模块中的start_new_thread()函数来产生新线程