我编写了一个Python程序,它通过子类化的Process对象采用多处理。我目前正在尝试改进错误处理,但是由于我无法理解的原因,这让我感到沮丧。
在我列出一些示例代码时请耐心等待:
我的子流程工作者:
# worker.py
from multiprocessing import Process, Queue
import sys
import traceback
# other imports as necessary
class Worker(Process):
def __init__(self, inputQueue, outputQueue):
try:
super(Worker, self).__init__()
self.inputQueue = inputQueue
self.outputQueue = outputQueue
#etc
1/0 # dumb error that causes the process to crash
#etc
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
e = traceback.format_exception(exc_type, exc_value, exc_traceback, limit = 2)
# Forward the error message to the Engine class
self.outputQueue.put({ 'type' : 'error', 'data' : e })
def run(self):
try:
for i in iter(self.inputQueue.get, 'STOP'):
# Do stuff
self.outputQueue.put({ 'type' : 'result', 'data' : stuff })
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
e = traceback.format_exception(exc_type, exc_value, exc_traceback, limit = 2)
# Forward the error message to the Engine class
self.outputQueue.put({ 'type' : 'error', 'data' : e })
这是我的Engine类,它是Worker对象的父级:
# engine.py
# imports as necessary
class Engine:
def __init__(self) # Other arguments as necessary
# Initialise the class
self.processors = []
def run(self):
try:
# Fill the inputQueue with a number of jobs
# and initialise the output queue
# etc
# Start the Worker processes
for i in range(numberOfProcesses):
p = worker.Worker(inputQueue, outputQueue)
self.processors.append(p)
p.start()
inputQueue.put('STOP')
# Process outputQueue
numberOfJobs = 6 # (say)
while numberOfJobs:
result = outputQueue.get()
if result['type'] == 'error':
print result
raise Exception
elif result['type'] == 'result':
# Process result appropriately
numberOfJobs -= 1
for p in self.processors:
p.join()
except Exception as e:
raise
运行整个事情的配置文件:
# configuration.py
if __name__ == "__main__":
# Initialise other parameters as necessary
try:
# Initialise an instance of engine.Engine
eng = engine.Engine(arguments as necessary)
eng.run()
except Exception as e:
print e
print 'Finished UNSUCCESSFULLY.'
else:
print 'Finished SUCCESSFULLY.'
为简洁起见,我在示例代码中留下了一些导入和其他内容。 worker.py中的错误处理机制来自我之前的问题here。
当我运行程序时,工作进程执行,当一个人遇到Worker.__init__
(或Worker.run()
中的1/0错误时,如果其中有一个错误),它会抓取回溯并且将它放入输出队列就好了。 Engine.run()
按预期打印错误消息。问题是这一切都结束了。引擎应引发 new ,泛型,错误,并且(我认为)将其传递给configuration.py中的代码,然后程序应该通过except语句退出文件(打印一条消息,上面写着'完成不成功')。
相反,实际发生的是Engine.run()
打印从Worker类派生的错误消息,然后程序挂起并且CPU使用率降至0%。没有其他事情发生。我认识到这很可能是其他工人流程没有退出的问题(或者他们应该做的任何事情)。
令我神秘的是,如果我在Engine类中没有except Exception as e
块,并且我在configuration.py文件中没有try-except-else
块,{{1从Worker对象打印回溯,然后使用通用Engine.run()
语句正确崩溃(不挂起)。
基本上我想做的是让raise Exception
将泛型引发异常传递给配置文件,以便程序更优雅地退出。
有人帮助我!