Search code examples
pythonpyqt5pyinstaller

Different behaviors of process, before vs after PyInstaller


This is for a PyQt GUI, in which the user can start a process running a new "session" (basically another instance of the entire thing/window). I also want to send some info, say window position or save data dirs, to the new session, only once when the new process start. I want the new session to run independently of the old/original session, as when user closes out the old one, it won't terminate the new session. The program runs fine as a python script, but after I package it with pyinstaller ./main.py, the behavior changes.

I believe this is more of a problem of how pyinstaller handles multiprocessing, as in the simplified example below, I got similar problem.

import time
from random import random
from multiprocessing import Process

# foo will be a qMainWindow class in the real gui.
class foo():
    def __init__(self, new_foo_func, previous_rand = None) -> None:
        self.new_foo_func = new_foo_func
        self.rand_num = random()
        print('Random number of this foo: {0}'.format(self.rand_num))
        print('Random number of previous foo: {0}'.format(previous_rand))

        time.sleep(2)
        print('Trying to start a new foo')
        self.startNewFoo()
    
    # This simulate when user want to have a new session
    def startNewFoo(self):
        self.new_foo_func(self.rand_num)

def newFooFunc(previous_rand):
    foo(newFooProc, previous_rand)
    
def newFooProc(previous_rand = None):
    newProcess = Process(target=newFooFunc, args=([previous_rand]))
    newProcess.start()
    newProcess.join()

if __name__ == '__main__':
    print('Starting of the program ...')
    newFooProc()

When run as a script, it outputs as expected:

Starting of the program ...
Random number of this foo: 0.341067188561644
Random number of previous foo: None
Trying to start a new foo
Random number of this foo: 0.029693107517033468
Random number of previous foo: 0.341067188561644
Trying to start a new foo
Random number of this foo: 0.15047371562131218
Random number of previous foo: 0.029693107517033468
...

When it is run as a pyinstaller package, it keep looping through the main part. It didn't even wait for the time.sleep().

Starting of the program ...
Starting of the program ...
Starting of the program ...
Starting of the program ...
Starting of the program ...
Starting of the program ...
Starting of the program ...
Starting of the program ...
Starting of the program ...

I am using pyinstaller 6.1.0, and python 3.9.16. But I feel it might also applies to other versions, or even OS. I have a macbook with slightly different python/pyinstaller config, and have similar problem.

Also I have to admit I am not sure I am implementing this properly. If you know some other ways to implement this, please let me know and I am happy to try.


Solution

  • See also
    Basically, add multiprocessing.freeze_support() to your program.
    Documented here