Question

I'm working on porting an early version of a project to Windows and distributing it as a binary. The project so far has been developed in Arch Linux with Python 3.3, but I want to package it as a standalone binary in Windows order to reach a larger test audience. I've confirmed that the code runs as expected in Windows with Python 3.3.

Upon trying to compile it with cxfreeze, I run into some issues. First, the main library I use (sc2reader), contains data in the form of .csv files. In Windows, these files are located in \Python33\Lib\site-packages\sc2reader, but cxfreeze neglects to include them while including most of the .py files associated with sc2reader. Initially, the generated executable would crash immediately, complaining about these missing data files. After manually adding them (I couldn't get setup.py to include these files--cxfreeze wouldn't complain about any syntax errors, but it wouldn't include the files either), I got rid of these errors.

My setup.py looks like this:

import sys

from cx_Freeze import setup, Executable

build_exe_options = {"include_files": ['C:\Python33\Lib\site-packages\sc2reader\data\']}

setup(
    name = "vroMAD",
    version = "0.1.0",
    executables = [Executable("__main__.py", base = "base")]

After manually copying files over, I at least got the binary to start. It draws the window correctly, but some of the behaviors are incorrect. Basic functions such file browsing and file selection work, but that's about it. There's a button in the window that executes a long task and paints a progress bar. Because this long task would block the GUI from updating, a second process is spawned whenever the user pushes this button. However, instead of proceeding with the task and updating the progress bar, the program creates a duplicate window. In fact, Task Manager shows an additional, identical process. The new window behaves exactly like the old one: it handles basic events correctly, but when the button is pushed, it spawns yet another window... which behaves in the same way.

Does multiprocessing not work with cxfreeze?

Was it helpful?

Solution

Are you calling multiprocessing.freeze_support?

Add support for when a program which uses multiprocessing has been frozen to produce a Windows executable. (Has been tested with py2exe, PyInstaller and cx_Freeze.)

One needs to call this function straight after the if __name__ == '__main__' line of the main module. For example:

from multiprocessing import Process, freeze_support

def f():
    print 'hello world!'

if __name__ == '__main__':
    freeze_support()
    Process(target=f).start()

If the freeze_support() line is omitted then trying to run the frozen executable will raise RuntimeError.

If the module is being run normally by the Python interpreter then freeze_support() has no effect.

Also, you are wrapping all the executing code in if __name__ == '__main__', right? multiprocessing behaves differently in that way on Windows vs Unix (because of the lack of fork()).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top