5

This is pretty much the same as this question, but the given solution there (calling freeze_support()) does not work for me.

I have the following script called start.py that I use to build a standalone executable with py2exe (version 0.9.2.2). I also have python.exe in the same directory.

import multiprocessing

def main():
    print('Parent')
    p = multiprocessing.Process(target=new_process)
    multiprocessing.set_executable('python.exe')
    p.start()
    p.join()

def new_process():
    print('Child')

if __name__ == '__main__':
    multiprocessing.freeze_support()
    main()

It works perfectly fine when run as pure python. However, when packaged as an executable, this is the error I get:

Unknown option: --
usage: <path to start.exe> [option] ... [-c cmd | -m mod | file | -] [arg] ...
Try `python -h' for more information.

This is clearly caused by calling

python.exe --multiprocessing-fork

If I don't call set_executable() and freeze_support(), the child process just starts up the exe and runs as __main__, causing an endless chain of new processes to print "Parent" while "Child" is never printed.

The only thing calling freeze_support() seems to do is cause the child process to raise the following error if I don't call multiprocessing.set_executable()

Traceback (most recent call last):
  File "start.py", line 17, in <module>
    multiprocessing.freeze_support()
  File "C:\Python34\Lib\multiprocessing\context.py", line 148, in freeze_support

    freeze_support()
  File "C:\Python34\Lib\multiprocessing\spawn.py", line 67, in freeze_support
    main()
NameError: name 'main' is not defined

I'm using Python 3.4 32-bit running on Windows 8.1 64 bit. I've tried everything above using cx-Freeze with the same results. Any help would be much appreciated.

EDIT: Even when using this example straight out of the docs:

from multiprocessing import Process, freeze_support

def f():
    print('hello world!')

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

I get the same NameError when the child process calls freeze_support().

Mobious
  • 122
  • 8
  • My tool [pynsist](http://pynsist.readthedocs.org/en/latest/) might be useful. It doesn't make your code an exe, so you shouldn't need any special tricks to make multiprocessing work. It builds an installer that sets up Python itself along with your code. – Thomas K Mar 18 '15 at 18:44
  • 1
    I was able to get it working using Python 2.7.9 and py2exe 0.6.9 provided I removed the call to set_executable but still called freeze_support(). My best guess is that freeze_support() isn't functioning properly in Python 3. – Mobious Mar 18 '15 at 19:23

1 Answers1

2

Try the suggested fix in the docs:

multiprocessing.set_executable(os.path.join(sys.exec_prefix, 'pythonw.exe'))

Also note that you need to call this before spawning any new processes.

Jonathan
  • 8,453
  • 9
  • 51
  • 74
Patrick Collins
  • 10,306
  • 5
  • 30
  • 69
  • This gives me the same result as what I currently have. I tried moving set_executable to before initializing the process, and under if \__name__ == '\__main__' both before and after the call to freeze_support(), all to no effect. – Mobious Mar 18 '15 at 17:11
  • 1
    Just another thing to note: sys.exec_prefix is actually an empty string in the packaged executable. If I didn't include the python.exe in the working directory, I would get a FileNotFoundError since multiprocessing can't find the python.exe. – Mobious Mar 18 '15 at 18:27
  • I was having this exact problem. Rather than using `python.exe` you should be using `pythonw.exe` that seems to be solving `Unknown option: --` – Jonathan Jul 28 '16 at 13:48