到目前为止,我这样做了:
rets=set(pool.map_async(my_callback, args.hosts).get(60*4))
如果超时,我得到一个例外:
File "/usr/lib/python2.7/multiprocessing/pool.py", line 524, in get
raise TimeoutError
multiprocessing.TimeoutError
我想优雅地处理这个问题:
我可以访问的所有主机的输出应该进入rets
,所有超时的主机应该进入单独的列表。
怎么可以这样做?
答案 0 :(得分:6)
据我所知,你不能,或者至少不在map_async
。 map_async
是一种解决特定用例特定问题的便捷方法,并且与您所获得的内容不匹配,因为您需要更精细的控制。
但是,您仍然可以这样做,您只需要在多处理模块中使用更细粒度的方法。特别是,您可以使用apply_async
动态地向池中添加作业,这使您可以更好地控制如何处理单个任务的成功和失败。
下面是一个非常简单的例子,我认为你做了什么:
from multiprocessing.pool import Pool, TimeoutError
from time import sleep, time
def task_function(xx):
print('Task %d running' % xx)
sleep(xx)
print('Task %d ended' % xx)
return 'Result of task %d' % xx
pl = Pool()
results = [
pl.apply_async(task_function, (_xx,))
for _xx in range(10)]
start = time()
wait_until = start + 5
rets = []
timed_out_results = []
for res in results:
timeout = wait_until - time()
if timeout < 0:
timeout = 0
try:
rets.append(res.get(timeout))
except TimeoutError:
timed_out_results.append(res)
print('%s ended' % (rets,))
print('%s timedout' % (timed_out_results,))
这会运行10个作业,打印一行,睡眠,然后打印另一行。第一个睡眠为0秒,下一个为1,下一个为2等。我们在5秒后超时,因此我们预计5个任务已完成,5个任务已超时。
请注意我还没有停止仍在运行的任务,因此在现实世界中,它们可以在打印结果所需的时间内继续并完成。你必须弄清楚你对此有多关心/该怎么做。