0

如果我调用apply_async 10,000 次,假设OOM-killer 不干扰,多处理会同时启动它们,还是分批启动它们。例如.. 每 100 次启动,等待 90 次启动完成再启动?

达斯汀

4

1 回答 1

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") 及其腌制整数参数)很小。

于 2013-11-16T22:54:37.937 回答