2015-03-18 13 views
5

Questo è più o meno lo stesso di this question, ma la soluzione fornita lì (chiamando freeze_support()) non funziona per me.Python 3.4 multiprocessing non funziona con py2exe

Ho il seguente script chiamato start.py che uso per creare un eseguibile standalone con py2exe (versione 0.9.2.2). Ho anche python.exe nella stessa 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() 

Funziona perfettamente quando eseguito come puro python. Tuttavia, quando confezionato come un eseguibile, questo è l'errore che ottengo:

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

Questo è chiaramente causato da chiamando

python.exe --multiprocessing-fork 

Se io non chiamo set_executable() e freeze_support(), la processo figlio avvia appena l'exe e viene eseguito come __main__, causando una catena infinita di nuovi processi per stampare "Parent" mentre "Child" non viene mai stampato.

L'unica cosa che chiama freeze_support() sembra fare è provocare il processo figlio per alzare il seguente errore se non chiamo 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 

sto usando Python 3.4 32- bit in esecuzione su Windows 8.1 a 64 bit. Ho provato tutto sopra usando cx-Freeze con gli stessi risultati. Qualsiasi aiuto sarebbe molto apprezzato.

EDIT: Anche quando si usa questo esempio 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() 

ottengo lo stesso NameError quando il processo figlio chiama freeze_support().

+0

Il mio strumento [pynsist] (http://pynsist.readthedocs.org/en/latest/) potrebbe essere utile. Non rende il tuo codice un exe, quindi non dovresti aver bisogno di trucchi speciali per fare un lavoro di multiprocessing. Costruisce un programma di installazione che configura Python stesso insieme al tuo codice. –

+0

Sono riuscito a farlo funzionare usando Python 2.7.9 e py2exe 0.6.9 a condizione di aver rimosso la chiamata a set_executable, ma ho comunque chiamato freeze_support(). La mia ipotesi migliore è che freeze_support() non funzioni correttamente in Python 3. – Mobious

risposta

2

Prova la correzione suggerita in the docs:

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

Si noti inoltre che è necessario chiamare questo prima di deposizione delle uova eventuali nuovi processi.

+0

Questo mi dà lo stesso risultato di quello che ho attualmente. Ho provato a spostare set_executable prima di inizializzare il processo, e sotto if \ __ name__ == '\ __ main__' sia prima che dopo la chiamata a freeze_support(), tutto senza alcun effetto. – Mobious

+1

Solo un'altra cosa da notare: sys.exec_prefix è in realtà una stringa vuota nell'eseguibile pacchetto. Se non includessi python.exe nella directory di lavoro, otterrei un errore FileNotFoundError poiché il multiprocessing non riesce a trovare python.exe. – Mobious

+0

Stavo avendo questo problema esatto. Piuttosto che usare 'python.exe' dovresti usare' pythonw.exe' che sembra risolvere l'opzione 'Unknown: --' – Jonathan