Вы что-то смешиваете здесь.Пул всегда поддерживает количество указанных процессов.До тех пор, пока вы не закроете пул, либо вручную, либо оставив блок with в контекстном менеджере, вам не нужно будет пополнять пул процессами, потому что они никуда не денутся.
То, что вы, вероятно, хотели сказать, это «задачи», задачи, над которыми могут работать эти процессы.Задача - это блок процесса для итерируемого, который вы передаете методам пула.И да, есть способ использовать незанятые процессы в пуле для новых задач до Все ранее поставленные в очередь задачи были обработаны.Вы уже выбрали правильный инструмент для этого - асинхронные версии методов пула.Все, что вам нужно сделать, это повторно применить какой-то метод асинхронного пула.
from multiprocessing import Pool
import os
def busy_foo(x):
x = int(x)
for _ in range(x):
x - 1
print(os.getpid(), ' returning: ', x)
return x
if __name__ == '__main__':
arguments1 = zip([222e6, 22e6] * 2)
arguments2 = zip([111e6, 11e6] * 2)
with Pool(4) as pool:
results = pool.starmap_async(busy_foo, arguments1)
results2 = pool.starmap_async(busy_foo, arguments2)
print(results.get())
print(results2.get())
Пример вывода:
3182 returning: 22000000
3185 returning: 22000000
3185 returning: 11000000
3182 returning: 111000000
3182 returning: 11000000
3185 returning: 111000000
3181 returning: 222000000
3184 returning: 222000000
[222000000, 22000000, 222000000, 22000000]
[111000000, 11000000, 111000000, 11000000]
Process finished with exit code 0
Примечание выше, процессы 3182 и 3185, которые заканчиваются сболее простая задача, немедленно начните с задач из второго списка аргументов, не дожидаясь завершения 3181 и 3184.
Если вы по какой-то причине действительно хотите использовать свежие процессы после некоторого количества обработанных задачдля каждого процесса есть параметр maxtasksperchild
для Pool
.Там вы можете указать, через сколько задач пул должен заменить старые процессы новыми.Значением по умолчанию для этого аргумента является None
, поэтому пул не заменяет процессы по умолчанию.