问题背景:
主进程做任务调度,子进程做任务执行,子进程定时返回进度信息,主进程获取进度,进度为100时,子进程任务结束。子进程执行过程中如果有异常,主进程需要捕获
python多进程调度, 主进程如何捕获子进程的异常,这个问题困扰了好久,网上看了好多方法都不是我想要的,整理了一下遇到的一些坑
为了简化子进程任务实现,和主进程的任务等待的过程,直接用time.sleep(),先看下最终实现方案:
from multiprocessing import Pool
import time
def sub_task():
print "sub_task():enter sub_task"
loop_num = 0
while True:
print "sub_task:enter sub process loop"
if loop_num > 1:
print 'sub_task():sub_task finish'
raise Exception("sub_task has error")
loop_num += 1
time.sleep(1)
if __name__ == "__main__":
try:
proc_pool = Pool(processes=6)
result = proc_pool.apply_async(sub_task, args=())
proc_pool.close()
count = 0
while True:
print "main():enter main process loop"
time.sleep(2)
if result.ready():
print 'main():sub process is finish'
result.get()
if count > 1:
break
count += 1
print "main():main process finish"
except Exception as err_msg:
print "main():error mesage=%s" % str(err_msg)
proc_pool.terminate()
有异常的执行结果:
执行结果
子进程每隔一秒打印一次,打印2次后退出,主进程每隔1秒判断一次,当子进程执行完完是获取结果,如果有异常调到except直接捕获打印出来,没有异常执行打印语句(把子进程的异常删除或者把主进程循环时间改小或者把循环次数改小),主进程退出
没有异常的执行结果:
执行结果
遇到的坑:
在子进程中添加一个try-except:子进程能捕获自己的异常,不能反馈到主进程中
def sub_task():
try:
print "sub_task():enter sub_task"
loop_num = 0
while True:
print "sub_task:enter sub process loop"
if loop_num > 1:
print 'sub_task():sub_task finish'
raise Exception("sub_task has error")
loop_num += 1
time.sleep(1)
except Exception as err_msg:
print "sub_task():error mesage=%s" % str(err_msg)
执行结果
在主进程中直接增加result.get(),这样做主进程一直会等待子进程结束,主进程循环只能进去一次
if __name__ == "__main__":
try:
proc_pool = Pool(processes=6)
result = proc_pool.apply_async(sub_task, args=())
proc_pool.close()
count = 0
while True:
print "main():enter main process loop"
time.sleep(0.3)
result.get()
if count > 1:
break
count += 1
print "main():main process finish"
except Exception as err_msg:
print "main():error mesage=%s" % str(err_msg)
proc_pool.terminate()
执行结果