multiprocessing.Pool
hat bereits eine gemeinsame Ergebniswarteschlange, es ist nicht erforderlich, zusätzlich a einzubeziehen Manager.Queue
. Manager.Queue
ist 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.Queue
auch 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.worker
unter der Haube aus. Diese Funktion kümmert sich um die Verarbeitung neuer "Aufgaben", die über den internen Pool übertragen wurden, Pool._inqueue
und um das Zurücksenden der Ergebnisse an den übergeordneten Pool über den Pool Pool._outqueue
. Ihre Angabe func
wird innerhalb ausgeführt multiprocessing.pool.worker
. func
muss nur return
etwas und das Ergebnis wird automatisch an die Eltern zurückgesendet.
.apply_async()
gibt sofort (asynchron) ein AsyncResult
Objekt 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 timeout
Parameter-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
.