Search code examples
pythonwindowsmultiprocessingcx-freeze

cx_Freeze executable runs multiple tasks when using multiprocessing and freeze_support


I build an executable with cx_Freeze. I always read that I need to include multiprocessing.freeze_support to avoid multiple tasks of the executable running in the task manager. But if I use multiprocessing and freeze_support I still get two tasks running in the task manager.

Here is my example GUI named test_wibu.py:

import multiprocessing
from multiprocessing import freeze_support
import threading
import queue
import tkinter as tk
import psutil

import time
from tkinter.filedialog import *
sys._enablelegacywindowsfsencoding()

def worker(pqueue):
    while True:
        obj = pqueue.get()
        obj.execute()
        del obj


if __name__ == '__main__':
    freeze_support()

    q = queue.Queue(maxsize=0)

    root = Tk()


    print('Doing something to build the software interface')
    time.sleep(3)

    label = Label(root, text='Software', anchor=CENTER)
    label.grid(column=0, row=0, sticky='nwse', padx=0, pady=0)

    pqueue = multiprocessing.Queue()

    pool = multiprocessing.Pool(1, worker, (pqueue,))

    parent = psutil.Process()

    q.put('stop')

    root.mainloop()

And my setup_wibu.py:

import os.path
from cx_Freeze import *


PYTHON_INSTALL_DIR = os.path.join(os.getenv('LOCALAPPDATA'), 'Programs', 'Python', 'Python36')
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')


executables = [
    Executable('test_wibu.py',
               base='Win32GUI',
               targetName='test.exe',
               )
]

options = {
    'build_exe': {
        'excludes': ['gtk', 'PyQt4', 'PyQt5', 'scipy.spatial.cKDTree', 'sqlite3', 'IPython'],
        'packages': [],
        'includes':['pkg_resources'],
        'include_files': [os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
                          os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll')]

    },
}

setup(
    name='Pest_wibu',
    version='1.0',
    executables=executables,
    options=options,

)

If I build the executable and run it I get in the task manager in "Details" two tasks named test.exe. Is this a normal behaviour? How can I avoid that the executable creates multiple tasks?


Solution

  • According to this excellent answer, the reason for the multiprocessing.freeze_support() call is

    lack of fork() on Windows (which is not entirely true). Because of this, on Windows the fork is simulated by creating a new process in which code, which on Linux is being run in child process, is being run.

    and thus not to avoid multiple tasks of the executable running in the task manager as stated in your premise.

    Therefore, the behavior you observe in the task manager is probably normal and can't be avoided.