当我多处理.pool.apply_async比我有处理器多次时会发生什么

时间:2014-05-05 20:38:22

标签: python multiprocessing python-3.3 asynchronous

我有以下设置:

results = [f(args) for _ in range(10**3)]

但是,f(args)需要很长时间才能计算出来。所以我想把多处理器扔到它身上。我想这样做:

pool = mp.pool(mp.cpu_count() -1) # mp.cpu_count() -> 8
results = [pool.apply_async(f, args) for _ in range(10**3)]

显然,我的计算机上没有1000个处理器,所以我担心:
以上调用是否导致1000个进程同时竞争CPU时间或7个进程同时运行,在前一个调用结束时迭代计算下一个f(args)

我想我可以做pool.async_map(f, (args for _ in range(10**3)))之类的事情来获得相同的结果,但这篇文章的目的是了解pool.apply_async的行为

2 个答案:

答案 0 :(得分:11)

您的进程中的进程数永远不会超过池中的工作程序(在您的情况下为mp.cpu_count() - 1。如果您调用apply_async并且所有工作人员都忙,则任务将排队一旦工人释放,就立即执行。你可以通过一个简单的测试程序看到这个:

#!/usr/bin/python

import time
import multiprocessing as mp

def worker(chunk):
    print('working')
    time.sleep(10)
    return

def main():
    pool = mp.Pool(2)  # Only two workers
    for n in range(0, 8):
        pool.apply_async(worker, (n,))
        print("called it")
    pool.close()
    pool.join()

if __name__ == '__main__':
    main()

输出如下:

called it
called it
called it
called it
called it
called it
called it
called it
working
working
<delay>
working
working
<delay>
working 
working
<delay>
working
working

答案 1 :(得分:6)

工作进程的数量完全由mp.pool()的参数控制。因此,如果mp.cpu_count()在您的方框中返回8,则将创建7个工作进程。

所有pool方法(其中apply_async())然后只使用那么多工作进程。在封面下,参数在主程序中被pickle并通过进程间管道发送到工作进程。这个隐藏的机器有效地创建了一个工作队列,固定数量的工作进程从中拉出工作描述(函数名+参数)。

除此之外,它只是魔术; - )