multiprocessing.Pool
вже має спільну чергу результатів, немає необхідності додатково залучати файл Manager.Queue
. Manager.Queue
- це queue.Queue
(багатопотокова черга) під капотом, розташована на окремому серверному процесі та виставлена через проксі. Це додає додаткові накладні витрати порівняно з внутрішньою чергою пулу. На відміну від сподівання на власну обробку результатів Пулу, результати Manager.Queue
також не гарантовано замовляють.
Робочі процеси не запускаються .apply_async()
, це вже трапляється під час створення екземпляра Pool
. Що це почалося , коли ви телефонуєте pool.apply_async()
нова «робота». Робочі процеси пулу запускають multiprocessing.pool.worker
-функцію під капотом. Ця функція піклується про обробку нових "завдань", переданих через внутрішній пул, Pool._inqueue
і про відправлення результатів батьківському по Pool._outqueue
. Вказане вами func
буде виконано протягом multiprocessing.pool.worker
. func
має лише return
щось, і результат буде автоматично відправлений батьківському.
.apply_async()
негайно (асинхронно) повертає AsyncResult
об’єкт (псевдонім для ApplyResult
). Вам потрібно зателефонувати .get()
(блокує) цей об’єкт, щоб отримати фактичний результат. Іншим варіантом буде реєстрація функції зворотного виклику , яка запускається, як тільки результат стає готовим.
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}')
Приклад результату:
<multiprocessing.queues.SimpleQueue object at 0x7fa124fd67f0>
<multiprocessing.pool.ApplyResult object at 0x7fa12586da20>
result: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Примітка: Вказівка timeout
-параметру для .get()
не зупинить фактичну обробку завдання в робочому середовищі, він лише розблокує очікувального батька, піднявши a multiprocessing.TimeoutError
.