我正在尝试找出一种在Python 3.6中使用multiprocessing
包来运行一组约100个任务的好方法,其中最多同时运行4个任务。我也想:
我不需要维护提交到池的任务的顺序(即我不需要队列)。任务总数(上面的“100”)并不过分,例如我不介意一次性提交它们并让它们排队等到工人可用。
我认为multiprocessing.Pool
非常适合这种情况,但我似乎找不到可以迭代调用的“获取下一个结果”方法。
这是否会让我自己从流程管理原语中解脱出来?或者Pool
(或我缺少的其他东西)可以支持这个工作流程吗?
对于上下文,我使用每个工作者调用一个可能需要几分钟的远程进程,并且有能力同时处理N个作业(在我上面的具体例子中为“4”)。
答案 0 :(得分:0)
我提出了以下模式(使用2名工人和6名工作,而不是4和100):
import random
import time
from multiprocessing import Pool, TimeoutError
from queue import Queue
def worker(x):
print("Start: {}".format(x))
time.sleep(5 * random.random()) # Sleep a random amount of time
if x == 2:
raise Exception("Two is bad")
return x
if __name__ == '__main__':
with Pool(processes=2) as pool:
jobs = Queue()
for i in range(6):
jobs.put(pool.apply_async(worker, [i]))
while not jobs.empty():
j = jobs.get(timeout=1)
try:
r = j.get(timeout=0.1)
print("Done: {}".format(r))
except TimeoutError as e:
jobs.put(j) # Not ready, try again later
except Exception as e:
print("Exception: {}".format(e))
似乎工作得很好:
Start: 0
Start: 1
Start: 2
Done: 1
Start: 3
Exception: Two is bad
Start: 4
Start: 5
Done: 3
Done: 4
Done: 5
Done: 0
我会看看我是否可以通过一般功能来管理排队。
我认为它的主要缺点是,已完成的工作可能会暂时被忽视,而未完成的工作会被轮询并可能超时。避免这种情况可能需要使用回调 - 如果它成为一个足够大的问题,我可能会将其添加到我的应用程序中。