如果我将apply_async调用10,000次,假设OOM杀手没有干扰,那么多处理会同时启动它们,还是会批量启动它们。例如..每100次启动,在开始之前等待90完成启动?
达斯汀
答案 0 :(得分:6)
apply_async()
是multiprocessing.Pool
个对象的方法,它将所有工作交付给您在创建Pool
时指定的进程数。只有那么多任务可以同时运行。其余的由多处理机器保存在队列(或管道)中,并在完成已分配的任务时自动发送到进程。对于所有您为多个工作项提供的Pool
方法,情况大致相同。
再澄清一点:apply_async
不会创建或启动任何进程。调用Pool()
时创建了这些流程。这些流程只是坐在那里等待你调用Pool
方法(如apply_async()
),要求完成一些真正的工作。
玩这个:
MAX = 100000
from time import sleep
def f(i):
sleep(0.01)
return i
def summer(summand):
global SUM, FINISHED
SUM += summand
FINISHED += 1
if __name__ == "__main__":
import multiprocessing as mp
SUM = 0
FINISHED = 0
pool = mp.Pool(4)
print "queuing", MAX, "work descriptions"
for i in xrange(MAX):
pool.apply_async(f, args=(i,), callback=summer)
if i % 1000 == 0:
print "{}/{}".format(FINISHED, i),
print
print "closing pool"
pool.close()
print "waiting for processes to end"
pool.join()
print "verifying result"
print "got", SUM, "expected", sum(xrange(MAX))
输出就像:
queuing 100000 work descriptions
0/0 12/1000 21/2000 33/3000 42/4000
... stuff chopped for brevity ...
1433/95000 1445/96000 1456/97000 1466/98000 1478/99000
closing pool
waiting for processes to end
... and it waits here "for a long time" ...
verifying result
got 4999950000 expected 4999950000
您只需观察其行为即可回答大部分问题。工作项目排队很快。当我们看到“关闭池”时,所有工作项都已排队,但已完成1478个,大约98000个仍在等待某些进程处理它们。
如果你从sleep(0.01)
中取出f()
,那么它的揭示就会少得多,因为结果几乎与工作项排队的速度一样快。
不管你怎么运行,内存使用仍然是微不足道的。这里的工作项(函数的名称("f"
)及其pickle整数参数)很小。