Python multiprocessing.Pool与崩溃的进程
其实,这些程序本来不应该崩溃,但它们就是会崩溃。有没有办法让multiprocessing.Pool或者其他的多进程工具在一个进程崩溃后重新启动它?如果没有,我该怎么做呢?
谢谢!
补充说明:给点背景信息。这个进程在Autodesk Maya里处理一些几何图形的工作,做得还不错。问题是,有时候我会遇到一个文件,它在完成后打开新场景时,Maya(或者mayapy)会完全退出,期间没有任何Python的警告、错误,或者Windows的关键进程错误。它就是突然崩溃了。很遗憾,我对此崩溃没有什么办法。
我希望能找到一种方法,能够重新启动那些因为崩溃而死掉的进程。
2 个回答
确实,正如masida所说,Python 3.3的错误处理要更好。在这里,我会检查当一个子进程悄无声息地死掉时是否超时。
这个解决办法是针对Python 3.3之前的版本和multiprocessing.pool的。当然,自己管理进程也是个不错的选择。
可以使用pool.map_async来异步运行进程,这样你就可以检查任务是否完成以及花了多长时间。如果任务花的时间太长(比如某个进程死掉了而没有返回),那么就用pool.terminate()来终止所有的池进程,然后重新开始。代码示例如下:
done = False # not finished yet
while not(done):
job_start = time.time() # start time
Jobs = pool.map_async(args) # asynchronous pool call
redo = False # no redo yet
while not(Jobs.ready()): # while jobs are not finished
if (time.time() - job_start) > maxWait: # check maximum time (user def.)
pool.terminate() # kill old pool
pool = multiprocessing.pool(args) # create new pool
redo = True # redo computation
break # break loop, (not finished)
if not(redo): # computation was successful
result = Jobs.get() # get results
done = True # exit outer while
另一个选择是对由pool.imap返回的迭代器使用超时,这个超时可以作为参数传递给迭代器的'next'方法,写作next(timeout)。如果某个进程超出了这个超时,主进程就会抛出multiprocessing.TimeoutError,然后可以在异常处理块中进行类似上面提到的操作,虽然我没有彻底测试过这个方法。
最近,Python 3.3的行为发生了变化,在某些情况下会抛出一个异常。具体的变化可以查看这个链接:http://hg.python.org/cpython/rev/6d6099f7fe89
导致这个问题的缺陷可以在这里找到:http://bugs.python.org/issue9205
不过,如果你手动创建工作进程(我在使用多进程时通常会这样做),你可以尝试使用Process.is_alive()这个函数来检查进程是否还在运行。相关的文档可以查看这里:http://docs.python.org/dev/library/multiprocessing#multiprocessing.Process.is_alive