Pool/starmap的Python多处理行为

Pool/starmap的Python多处理行为,python,multiprocessing,Python,Multiprocessing,我有一个程序使用多处理库来计算一些东西。大约有10K个输入需要计算,每个输入需要0.2秒到10秒之间 我当前的方法使用一个池: # Inputs signals = [list(s) for s in itertools.combinations_with_replacement(possible_inputs, 3)] # Compute with mp.Pool(processes = N) as p: p.starmap(compute_solutions, [(s, t0, t

我有一个程序使用多处理库来计算一些东西。大约有10K个输入需要计算,每个输入需要0.2秒到10秒之间

我当前的方法使用一个池:

# Inputs
signals = [list(s) for s in itertools.combinations_with_replacement(possible_inputs, 3)]

# Compute
with mp.Pool(processes = N) as p:
    p.starmap(compute_solutions, [(s, t0, tf, folder) for s in signals])
    print ("    | Computation done.")
我注意到,在最后300/400次输入检查时,程序变得慢了很多。我的问题是:
Pool
starmap()

根据我的观察,我相信如果我得到10K个输入,并且
N=4
(4个进程),那么2500个第一个输入分配给第一个进程,2500个紧接着第二个进程。。。每个进程都以串行方式处理其输入。 这意味着,如果某些进程在其他进程之前清除了队列,它们将无法执行新任务

这是正确的吗?

如果这是正确的,我怎样才能拥有一个可以用以下伪代码表示的更智能的系统:

workers = Initialize N workers
tasks = A list of the tasks to perform

for task in tasks:
    if a worker is free:
        submit task to this worker
    else:
        wait
谢谢你的帮助:)

注意:不同的地图功能有什么不同。我相信
map()
imap\u unordered()
imap
starmap
是存在的

它们之间的区别是什么?我们什么时候应该使用一个或另一个?

这意味着,如果某些进程在其他进程之前清除了队列,它们将无法执行新任务

这是正确的吗?

不需要。
multiprocess.Pool()
的主要目的是将传递的工作负载分散到其工作人员池中-这就是为什么它附带了所有这些映射选项-其各种方法之间的唯一区别在于工作负载的实际分布方式和结果返回的收集方式

在您的例子中,您正在为信号中的s生成的iterable将把它的每个元素(最终取决于信号的大小)发送给池中的下一个空闲工作程序(作为
计算解决方案(s,t0,tf,folder)
)一次调用一个(如果传递了
chunksize
参数,则为更多),直到整个iterable用完。您无法控制哪个工作进程执行哪个部分,tho

工作负载也可能分布不均匀-一个工人可能比另一个工人处理更多的条目,这取决于资源使用情况、执行速度、各种内部事件

但是,使用
map
imap
starmap
multiprocessing.Pool
方法,当它们在内部同步每个worker的返回以匹配源iterable时,您会得到均匀有序分布的错觉(即,结果的第一个元素将包含从被调用函数返回的结果,其中包含iterable的第一个元素)。如果您想查看下面实际发生的情况,可以尝试这些方法的异步/无序版本

因此,默认情况下,您可以使用更智能的系统,但如果您希望完全控制员工库,则始终可以使用

作为补充说明,如果您希望优化对iterable本身的访问(因为池映射选项将消耗大部分),您可以进行检查

最后,

它们之间的区别是什么?我们什么时候应该使用一个或另一个?


与其在这里引述,不如直接看一下,因为有一个很好的解释说明了它们之间的区别。

谢谢,我明天会更详细地看一看。再加上这个答案,我不完全确定它是否正确。我观察到的是,如果我将上述代码与一组例如2名工人一起使用,并且如果工作人员1ceive比worker 2接收的作业短得多,那么worker 1将在worker 2之前完成很长时间,因此,即使worker 2尚未启动的作业也可以转移到worker 1。在我的情况下,每个作业都会生成一个文件。有时,我不得不再等待10/12个小时,等待最后一个worker完成其作业(而且一个作业的持续时间不超过15/20 mns)。我用maxtaskperchild参数解决了这个问题。