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.