Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why python executable opens new window instance when function by multiprocessing module is called on windows

Short Question: Why python executable generated by pyinstaller opens new window instance when function by multiprocessing module is called on windows operating system

I have a GUI code written using pyside. Where when we click on simple button it will calculate factorial in another process (using multiprocessing module). It works as expected when I run python program. But after I create executable using PyInstaller and when I run using exe it is creating new window when function by multiprocessing module gets called. Here is the code and step by step process to reproduce the issue.

Code:

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_())
  1. Run the above code using windows command prompt or power shell

    pyinstaller.exe gui.py

  2. Open the dist/gui/gui.exe (dist\gui\gui.exe). You will have one window opens

enter image description here

When we click on button click it's calculating factorial but create a new window instance. It's weird. It's not happening when I execute program before I create executable or on linux. It's only happening when I execute generated python executable file

The screen shot after I click click button

enter image description here

like image 590
neotam Avatar asked Nov 28 '15 11:11

neotam


1 Answers

If you want to use multiprocessing as a frozen executable, you need to call multiprocessing.freeze_support() at the beginning of your main script. This will allow multiprocessing to "take over" when it spawns its worker processes.

See also https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing

like image 130
codewarrior Avatar answered Sep 17 '22 23:09

codewarrior