处理衍生进程中的异常

时间:2015-05-27 13:36:22

标签: python multiprocessing

我希望编写一个从另一个进程执行命令的进程。这涉及接收命令,处理它并用结果回复调用进程。在请求执行下一个命令之前,调用进程应等待回复。这是我到目前为止所提出的:

import multiprocessing
import time

class CommandProcessor(multiprocessing.Process):
    def __init__(self):
        multiprocessing.Process.__init__(self)
        self.command = multiprocessing.Queue()
        self.result = multiprocessing.Queue()

    def run(self):
        while True:
            c = self.command.get()
            if not c: break 
            self.result.put(str(c)) 

    def execute(self, n):
        self.command.put(n)
        return self.result.get()

    def stop(self):
        self.command.put(None)
        self.join()

try:
    p = CommandProcessor()
    p.start()
    r = p.execute(1)
    print("Result: "+r)
    r = p.execute(2)
    print("Result: "+r)
    r = p.execute(3)
    print("Result: "+r)
finally:
    p.stop()

我的设计至少存在一个问题。例如,如果CommandProcessor中存在异常,则主进程将无限期地在行return self.result.get()上等待。我可以为get()方法添加超时,但是我运行的一些命令需要相对较长的时间才能执行。所以超时必须足够长以保证它们的执行。我如何处理这个问题,以便在存在将有用的堆栈跟踪转储到标准输出的异常时两个进程都终止。

2 个答案:

答案 0 :(得分:0)

将其包裹在try/except

示例:除了

def execute(self, n):
    try:
        self.command.put(n)
        return self.result.get()
    except Exception as e:
        return e  #  TODO: Do something sensible here

答案 1 :(得分:0)

它是在生成的进程中执行的run()方法,因此您需要进行异常处理。这是一个例子,结果返回了堆栈跟踪。另外,请注意检测None命令的纠正方式(即"停止"信号)。

import traceback

class CommandProcessor():
    ...

    def run(self):
        while True:
            c = self.command.get()
            if c is None:
                break
            try:
                1/(c-2)  # Throws exception if c is 2.
            except:
                c = traceback.format_exc()
            self.result.put(str(c)) 

你得到的是1和3可以正常工作,而2错误:

Result: 1
Result: Traceback (most recent call last):
  File "a.py", line 17, in run
    1/(c-2)  # Throws exception if c is 2.
ZeroDivisionError: integer division or modulo by zero

Result: 3