Ich verwende Python multiprocessing.Pool Bibliothek mehrere Prozesse in der folgenden Art und Weise zu erstellen:PyInstaller eingebaute Windows-EXE nicht mit multiprocessing.pool
def parallel_function(f):
def easy_parallize(f, sequence):
""" assumes f takes sequence as input, easy w/ Python's scope """
pool = Pool(processes=8) # depends on available cores
result = pool.map(f, sequence) # for i in sequence: result[i] = f(i)
cleaned = [x for x in result if x is not None] # getting results
cleaned = np.asarray(cleaned)
pool.close()
pool.join()
return cleaned
return partial(easy_parallize, f)
wobei f die Funktion ist, die Arbeit und die Reihenfolge zu tun sind die Parameter, siehe http://zqdevres.qiniucdn.com/data/20150702120338/index.html für das Tutorial.
Das Projekt wird mit PyInstaller 3.1.1 in eine einzelne Windows EXE gepackt. mit der Option --onedir. PyInstaller erstellt die EXE ohne Probleme, und ich bin in der Lage, die Teile des Programms, die kein Multithreading verwenden, ohne Probleme auszuführen.
Mein Problem tritt auf, wenn ich versuche, die Teile des Programms, die die oben beschriebene Multiprocessing-Funktion verwenden, auszuführen. Dann schlägt das Programm mit der folgenden Fehlermeldung (geschrieben über und über die von jedem Kind Gewinde):
File "multiprocessing\context.py", line 148, in freeze_support
File "multiprocessing\spawn.py", line 74, in freeze_support
File "multiprocessing\spawn.py", line 106, in spawn_main
File "multiprocessing\spawn.py", line 115, in _main
File "multiprocessing\spawn.py", line 221, in prepare
File "multiprocessing\context.py", line 231, in set_start_method
RuntimeError: context has already been set
classifier_v3_gui returned -1
Die freeze_support kommt als Vorschlag von https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing, wo der Haupt den Anruf als erste Zeile enthalten soll:
if name == "__main__":
multiprocessing.freeze_support()
ein ähnliches Problem hat in PyInstaller-built Windows EXE fails with multiprocessing und bezieht sich auf die Lösung in dem obigen Link jedoch a) die diskutierte Lösung für --onedir für mich nicht diskutiert zu funktionieren scheint, wie Sie aus dem Fehler sehen Nachricht Ich bekomme, b) Ich weiß nicht, wie _Popen mit Pool-ing verwandt ist, also für --onefile, ich weiß nicht einmal wie um die Klassenredefinition zu implementieren.
Wenn ich multiprocessing.freeze_support() in main nicht benutze, verhält sich das Programm anders, als dass der RuntimeError nicht passiert, stattdessen bekomme ich die Verwendungshinweise für mein Programm immer wieder auf den cmd geschrieben, nehme ich an der erzeugten Prozesse, die versuchen, die EXE selbst zu nennen, was offensichtlich nicht ist, was passieren soll.
Unnötig zu sagen, das Programm läuft ohne Probleme als .py-Skript.
Ich bin mit 32-Bit-Python 3.4 auf Windows 10.
Die einzige andere Lösung (haben die gleiche Multithreading Problem mit Python 2.7 als auch hatte) ich denken kann, meine Lösung neu zu schreiben ist Multiprozessing zu verwenden. Prozess statt Multiprocessing.Pool, da scheint es eine Lösung zu geben. Wenn Sie einen ziemlich geringen Aufwand haben, um das zu tun, was meine Pool-Funktion macht, werde ich mich damit zufrieden geben.
Hallo @Mjellma könnten Sie bitte eine Antwort auf Ihre Frage geben? Ich verstehe, dass Sie mit diesem Fehler umgehen konnten. – mathiasfk