Python multiprocessing.Pool与崩溃的进程

4 投票
2 回答
4611 浏览
提问于 2025-04-17 01:37

其实,这些程序本来不应该崩溃,但它们就是会崩溃。有没有办法让multiprocessing.Pool或者其他的多进程工具在一个进程崩溃后重新启动它?如果没有,我该怎么做呢?

谢谢!

补充说明:给点背景信息。这个进程在Autodesk Maya里处理一些几何图形的工作,做得还不错。问题是,有时候我会遇到一个文件,它在完成后打开新场景时,Maya(或者mayapy)会完全退出,期间没有任何Python的警告、错误,或者Windows的关键进程错误。它就是突然崩溃了。很遗憾,我对此崩溃没有什么办法。

我希望能找到一种方法,能够重新启动那些因为崩溃而死掉的进程。

2 个回答

1

确实,正如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,然后可以在异常处理块中进行类似上面提到的操作,虽然我没有彻底测试过这个方法。

0

最近,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

撰写回答