import multiprocessing as mp
if __name__ == '__main__':
#pool = mp.Pool(M)
p1 = mp.Process(target= target1, args= (arg1,))
p2 = mp.Process(target= target2, args= (arg1,))
...
p9 = mp.Process(target= target9, args= (arg9,))
p10 = mp.Process(target= target10, args= (arg10,))
...
pN = mp.Process(target= targetN, args= (argN,))
processList = [p1, p2, .... , p9, p10, ... ,pN]
我有N个不同的目标函数,它们消耗不等的非平凡时间来执行。
我正在寻找一种并行执行它们的方法,以便M(1< M< N>)进程同时运行。一旦流程完成,下一个流程应该从列表开始,直到processList
中的所有流程都完成。
由于我没有调用相同的目标函数,因此我无法使用Pool
。
我考虑做过这样的事情:
for i in range(0, N, M):
limit = i + M
if(limit > N):
limit = N
for p in processList[i:limit]:
p.join()
由于我的目标函数消耗的执行时间不等,因此该方法效率不高。
有什么建议吗?提前谢谢。
编辑: 问题标题已从“执行没有多处理池的进程列表”更改为“执行没有多处理池映射的进程列表”。
答案 0 :(得分:4)
您可以使用proccess Pool:
#!/usr/bin/env python
# coding=utf-8
from multiprocessing import Pool
import random
import time
def target_1():
time.sleep(random.uniform(0.5, 2))
print('done target 1')
def target_2():
time.sleep(random.uniform(0.5, 2))
print('done target 1')
def target_3():
time.sleep(random.uniform(0.5, 2))
print('done target 1')
def target_4():
time.sleep(random.uniform(0.5, 2))
print('done target 1')
pool = Pool(2) # maximum two processes at time.
pool.apply_async(target_1)
pool.apply_async(target_2)
pool.apply_async(target_3)
pool.apply_async(target_4)
pool.close()
pool.join()
专门为您需要做的事情创建池 - 在有限数量的进程中执行许多任务。
我还建议您查看concurrent.futures
库,backport to Python 2.7。它有一个ProcessPoolExecutor
,它具有大致相同的功能,但它的方法返回Future
个对象,并且它们有一个更好的API。
答案 1 :(得分:3)
这是一种在Python 3.4中实现的方法,可以适用于Python 2.7:
targets_with_args = [
(target1, arg1),
(target2, arg2),
(target3, arg3),
...
]
with concurrent.futures.ProcessPoolExecutor(max_workers=20) as executor:
futures = [executor.submit(target, arg) for target, arg in targets_with_args]
results = [future.result() for future in concurrent.futures.as_completed(futures)]
答案 2 :(得分:1)
我会使用Queue
。从processList
向它添加进程,一旦进程完成,我会将其从队列中删除并添加另一个。
伪代码看起来像:
from Queue import Queue
q = Queue(m)
# add first process to queue
i = 0
q.put(processList[i])
processList[i].start()
i+=1
while not q.empty():
p=q.get()
# check if process is finish. if not return it to the queue for later checking
if p.is_alive():
p.put(t)
# add another process if there is space and there are more processes to add
if not q.full() and i < len(processList):
q.put(processList[i])
processList[i].start()
i+=1
答案 3 :(得分:0)
一个简单的解决方案是将函数target {1,2,... N}包装到单个函数forward_to_target中,该函数根据参数转发到适当的目标{1,2,... N}函数。传入。如果无法从当前使用的参数中推断出相应的目标函数,请用元组(argX,X)替换每个参数,然后在forward_to_target函数中解压缩元组并转发到X指示的相应函数。
答案 4 :(得分:0)
你可以有两个list
个目标和参数,zip
两个一起 - 并将它们发送给一个跑步者功能(这里是run_target_on_args
):
#!/usr/bin/env python
import multiprocessing as mp
# target functions
targets = [len, str, len, zip]
# arguments for each function
args = [["arg1"], ["arg2"], ["arg3"], [["arg5"], ["arg6"]]]
# applies target function on it's arguments
def run_target_on_args(target_args):
return target_args[0](*target_args[1])
pool = mp.Pool()
print pool.map(run_target_on_args, zip(targets, args))