multiprocessing.Poolhat bereits eine gemeinsame Ergebniswarteschlange, es ist nicht erforderlich, zusätzlich a einzubeziehen Manager.Queue. Manager.Queueist eine queue.Queue(Multithreading-Warteschlange) unter der Haube, die sich auf einem separaten Serverprozess befindet und über Proxys verfügbar gemacht wird. Dies erhöht den Overhead im Vergleich zur internen Warteschlange von Pool. Im Gegensatz zur nativen Ergebnisbehandlung von Pool kann Manager.Queueauch nicht garantiert werden , dass die Ergebnisse in der Reihenfolge bestellt werden.
Die Worker-Prozesse werden nicht gestartet .apply_async(). Dies geschieht bereits beim Instanziieren Pool. Was wird gestartet , wenn Sie anrufen pool.apply_async()ist ein neuer „Job“. Die Arbeitsprozesse von Pool führen die Funktion multiprocessing.pool.workerunter der Haube aus. Diese Funktion kümmert sich um die Verarbeitung neuer "Aufgaben", die über den internen Pool übertragen wurden, Pool._inqueueund um das Zurücksenden der Ergebnisse an den übergeordneten Pool über den Pool Pool._outqueue. Ihre Angabe funcwird innerhalb ausgeführt multiprocessing.pool.worker. funcmuss nur returnetwas und das Ergebnis wird automatisch an die Eltern zurückgesendet.
.apply_async() gibt sofort (asynchron) ein AsyncResultObjekt zurück (Alias für ApplyResult). Sie müssen .get()dieses Objekt aufrufen (blockiert es), um das tatsächliche Ergebnis zu erhalten. Eine andere Möglichkeit wäre, eine Rückruffunktion zu registrieren , die ausgelöst wird, sobald das Ergebnis fertig ist.
from multiprocessing import Pool
def busy_foo(i):
"""Dummy function simulating cpu-bound work."""
for _ in range(int(10e6)): # do stuff
pass
return i
if __name__ == '__main__':
with Pool(4) as pool:
print(pool._outqueue) # DEMO
results = [pool.apply_async(busy_foo, (i,)) for i in range(10)]
# `.apply_async()` immediately returns AsyncResult (ApplyResult) object
print(results[0]) # DEMO
results = [res.get() for res in results]
print(f'result: {results}')
Beispielausgabe:
<multiprocessing.queues.SimpleQueue object at 0x7fa124fd67f0>
<multiprocessing.pool.ApplyResult object at 0x7fa12586da20>
result: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Hinweis: Wenn Sie den timeoutParameter-für angeben, .get()wird die eigentliche Verarbeitung der Aufgabe innerhalb des Workers nicht gestoppt, sondern nur das wartende übergeordnete Element durch Auslösen von a entsperrt multiprocessing.TimeoutError.