python主线程捕获子线程的方法


Posted in Python onJune 17, 2018

最近,在做一个项目时遇到的了一个问题,主线程无法捕获子线程中抛出的异常。

先看一个线程类的定义

''''' 
Created on Oct 27, 2015 
 
@author: wujz 
''' 
import threading 
 
class runScriptThread(threading.Thread): 
 def __init__(self, funcName, *args): 
  threading.Thread.__init__(self) 
  self.args = args 
  self.funcName = funcName 
  
 def run(self): 
  try: 
   self.funcName(*(self.args)) 
  except Exception as e: 
   raise e

很简单,传入要调用的方法,并启用一个新的线程来运行这个方法。

在主线程中,启动这个线程类的一个对象时,这要声明一个对象然后启动就可以了,示例如下

import runScriptThread,traceback 
 
if __name__=='__main__': 
 sth = 'hello world' 
 try: 
  aChildThread = runScriptThread(printSth, sth) 
  aChildThread.start() 
  aChildThread.join() 
 except Exception as e: 
  print(str(traceback.format_exc()))

但是这样的代码,main方法中无法捕获子线程中的异常,原因在于start()方法将为子线程开辟一条新的栈,main方法的栈因此无法捕获到这一异常。

解决方法很简单,就是通过设置一个线程是否异常退出的flag的成员变量,当线程异常退出时,对其作一标记。然后在主线程中检查改线程运行结束后该标志位的值,如果异常,再通过sys和traceback回溯异常信息,然后抛出即可。改写后的异常类:

''''' 
Created on Oct 27, 2015 
 
@author: wujz 
''' 
import threading,traceback,sys 
 
class runScriptThread(threading.Thread): #The timer class is derived from the class threading.Thread 
 def __init__(self, funcName, *args): 
  threading.Thread.__init__(self) 
  self.args = args 
  self.funcName = funcName 
  self.exitcode = 0 
  self.exception = None 
  self.exc_traceback = '' 
  
 def run(self): #Overwrite run() method, put what you want the thread do here 
  try: 
   self._run() 
  except Exception as e: 
   self.exitcode = 1  # 如果线程异常退出,将该标志位设置为1,正常退出为0 
   self.exception = e 
   self.exc_traceback = ''.join(traceback.format_exception(*sys.exc_info())) #在改成员变量中记录异常信息 
  
 def _run(self): 
  try: 
   self.funcName(*(self.args)) 
  except Exception as e: 
   raise e

改写后的主线程:

import runScriptThread,traceback 
 
if __name__=='__main__': 
 sth = 'hello world' 
 try: 
  aChildThread = runScriptThread(printSth, sth) 
  aChildThread.start() 
  aChildThread.join() 
 except Exception as e: 
  print(aChildThread.exc_traceback)

以上全部为本篇文章的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python ljust rjust center输出
Sep 06 Python
Python实现字典依据value排序
Feb 24 Python
分析Python中设计模式之Decorator装饰器模式的要点
Mar 02 Python
python 编程之twisted详解及简单实例
Jan 28 Python
Python初学时购物车程序练习实例(推荐)
Aug 08 Python
Python之Scrapy爬虫框架安装及使用详解
Nov 16 Python
python登录并爬取淘宝信息代码示例
Dec 09 Python
Python音频操作工具PyAudio上手教程详解
Jun 26 Python
解析Python3中的Import
Oct 13 Python
全网首秀之Pycharm十大实用技巧(推荐)
Apr 27 Python
python 自定义异常和主动抛出异常(raise)的操作
Dec 11 Python
python 如何在list中找Topk的数值和索引
May 20 Python
Python实现获取邮箱内容并解析的方法示例
Jun 16 #Python
Python实现自定义函数的5种常见形式分析
Jun 16 #Python
Python基于jieba库进行简单分词及词云功能实现方法
Jun 16 #Python
Python实现简单的文本相似度分析操作详解
Jun 16 #Python
Django跨域请求问题的解决方法示例
Jun 16 #Python
Python for循环生成列表的实例
Jun 15 #Python
Python把csv数据写入list和字典类型的变量脚本方法
Jun 15 #Python
You might like
PHP与javascript对多项选择的处理
2006/10/09 PHP
PHPMailer邮件类利用smtp.163.com发送邮件方法
2008/09/11 PHP
PHP中使用mktime获取时间戳的一个黑色幽默分析
2012/05/31 PHP
PHP OPP机制和模式简介(抽象类、接口和契约式编程)
2014/06/09 PHP
微信支付PHP SDK之微信公众号支付代码详解
2015/12/09 PHP
jquery鼠标放上去显示悬浮层即弹出定位的div层
2014/04/25 Javascript
NodeJS学习笔记之MongoDB模块
2015/01/13 NodeJs
jQuery在ul中显示某个li索引号的方法
2015/03/17 Javascript
JS设置网页图片vspace和hspace属性的方法
2015/04/01 Javascript
jQuery插件jRumble实现网页元素抖动
2015/06/05 Javascript
Vue2实现组件props双向绑定
2016/12/02 Javascript
vue配置多页面的实现方法
2018/05/22 Javascript
使用javascript函数编写简单银行取钱存钱流程
2018/05/26 Javascript
vue多层嵌套路由实例分析
2019/03/19 Javascript
vue router导航守卫(router.beforeEach())的使用详解
2019/04/19 Javascript
python虚拟环境 virtualenv的简单使用
2020/01/21 Javascript
node.js中npm包管理工具用法分析
2020/02/14 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
2020/02/14 Javascript
JSON获取属性值方法代码实例
2020/06/30 Javascript
原生JS实现拖拽功能
2020/12/16 Javascript
Python实现监控程序执行时间并将其写入日志的方法
2015/06/30 Python
Python实现 多进程导入CSV数据到 MySQL
2017/02/26 Python
Python学习笔记之pandas索引列、过滤、分组、求和功能示例
2019/06/03 Python
Python线上环境使用日志的及配置文件
2019/07/28 Python
python文件读写代码实例
2019/10/21 Python
python读取多层嵌套文件夹中的文件实例
2020/02/27 Python
Python导入数值型Excel数据并生成矩阵操作
2020/06/09 Python
瑞典Happy Socks美国官网:购买色彩斑斓的快乐袜子
2016/10/19 全球购物
Dower & Hall官网:英国小众轻奢珠宝品牌
2019/01/31 全球购物
写clone()方法时,通常都有一行代码,是什么?
2012/10/31 面试题
代码中finally中的代码会不会执行
2012/02/06 面试题
护理专业的自荐信
2013/10/22 职场文书
美容院营销方案
2014/03/05 职场文书
大学生敬老院活动总结
2015/05/07 职场文书
基于Redis过期事件实现订单超时取消
2021/05/08 Redis
python+pytest接口自动化之token关联登录的实现
2022/04/06 Python