Здесь программа:
#!/usr/bin/python
import multiprocessing
def dummy_func(r):
pass
def worker():
pass
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=16)
for index in range(0,100000):
pool.apply_async(worker, callback=dummy_func)
# clean up
pool.close()
pool.join()
Я нашел, что использование памяти (как VIRT, так и RES) продолжало расти до закрытия()/join(), есть ли решение, чтобы избавиться от этого? Я пробовал maxtasksperchild с 2,7, но это тоже не помогло.
У меня есть более сложная программа, которая вызывает apply_async() ~ 6M раз, а в точке ~ 1.5M у меня уже есть 6G + RES, чтобы избежать всех других факторов, я упростил программу до версии.
EDIT:
Оказалось, что эта версия работает лучше, спасибо за вход:
#!/usr/bin/python
import multiprocessing
ready_list = []
def dummy_func(index):
global ready_list
ready_list.append(index)
def worker(index):
return index
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=16)
result = {}
for index in range(0,1000000):
result[index] = (pool.apply_async(worker, (index,), callback=dummy_func))
for ready in ready_list:
result[ready].wait()
del result[ready]
ready_list = []
# clean up
pool.close()
pool.join()
Я не помещал туда никакой блокировки, так как я считаю, что основной процесс является однопоточным (обратный вызов более или менее похож на событие, управляемое событиями для каждого документа, которое я читаю).
Я изменил диапазон индексов v1 до 1 000 000, то же самое, что и v2, и сделал некоторые тесты - это странно для меня, v2 даже на ~ 10% быстрее, чем v1 (33s против 37s), возможно, v1 занимался слишком многими внутренними заданиями по обслуживанию списка. v2 определенно является победителем в использовании памяти, он никогда не превышал 300M (VIRT) и 50M (RES), в то время как v1 был 370M/120M, лучшим был 330M/85M. Все номера были всего 3 ~ 4 раза тестирования, только ссылки.