[Python]获取子线程异常信息
起因
今天在写东西的时候,用到了多线程。遇到了个问题:
子线程的异常,在父线程中无法捕获。
解决
问题代码
问题代码示例代码如下:
import threading
class SampleThread(threading.Thread):
    def run(self):
        raise Exception('An error occured here.')
def main():
    try:
        thread_obj = SampleThread()
        thread_obj.start()
    except Exception:
        print 'catch that'
if __name__ == '__main__':
    main()
运行输出结果如下:
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/path/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/PycharmProjects/example/threading_example.py", line 15, in run
    raise Exception('An error occured here.')
Exception: An error occured here.
解决办法
通过查看资料:http://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python
出现上述问题是因为:执行到 thread_obj.start() 时,父线程就会立即返回结果。然后,生成的子线程在自己独立的上下文中执行,并使用自己的堆栈。子线程发生的任何异常都是在子线程的上下文中,并且它在它自己的堆栈中(独立于父线程)。
所以,解决办法是:将这些信息传递给父线程。代码如下:
import sys
import threading
import Queue
class ExcThread(threading.Thread):
    def __init__(self, bucket):
        threading.Thread.__init__(self)
        self.bucket = bucket
    def run(self):
        try:
            raise Exception('An error occured here.')
        except Exception:
            self.bucket.put(sys.exc_info())
def main():
    bucket = Queue.Queue()
    thread_obj = ExcThread(bucket)
    thread_obj.start()
    while True:
        try:
            exc = bucket.get(block=False)
        except Queue.Empty:
            pass
        else:
            exc_type, exc_obj, exc_trace = exc
            # deal with the exception
            print exc_type, exc_obj
            print exc_trace
        thread_obj.join(0.1)
        if thread_obj.isAlive():
            continue
        else:
            break
if __name__ == '__main__':
	import sys
import threading
import Queue
class ExcThread(threading.Thread):
    def __init__(self, bucket):
		super(ExcThread, self).__init__()
        self.bucket = bucket
    def run(self):
        try:
            raise Exception('An error occured here.')
        except Exception:
			# 异常信息元祖放入队列传递给父进程
            self.bucket.put(sys.exc_info())
def main():
    bucket = Queue.Queue()
    thread_obj = ExcThread(bucket)
    thread_obj.start()
	# 循环获取子线程的异常信息
    while 1:
        try:
            exc = bucket.get(block=False)
        except Queue.Empty:
            pass
        else:
            exc_type, exc_obj, exc_trace = exc
            # deal with the exception
            print exc_type, exc_obj
            print exc_trace
        # 防止阻塞
        thread_obj.join(0.1)
        if thread_obj.isAlive():
            continue
        else:
            break
if __name__ == '__main__':
    main()
参考
[Python]获取子线程异常信息的更多相关文章
- python使用traceback获取详细的异常信息
		
原创来自:https://blog.csdn.net/mengtao0609/article/details/55049059 python使用traceback获取详细的异常信息 2017年02月1 ...
 - Java并发-UncaughtExceptionHandler捕获线程异常信息并重新启动线程
		
Java并发-UncaughtExceptionHandler捕获线程异常信息并重新启动线程 一.捕获异常并重新启用线程 public class Testun { public static voi ...
 - ARTS-S 获取子线程返回值注意事项
		
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h& ...
 - python获取系统内存占用信息的实例方法
		
psutil是一个跨平台库(http://code.google.com/p/psutil/),能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息.它主要应用于系统监控, ...
 - python主线程捕获子线程异常
		
python内置threading.Thread类创建的子线程抛出的异常无法在主线程捕获,可以对该类进行优化,为子线程添加exit code属性,主线程通过获取子线程的返回状态,来判断子线程中是否发生 ...
 - python多线程获取子线程任务返回值
		
今天想实现多线程更新资产信息,所以使用到了threading,但是我需要每个线程的返回值,这就需要我在threading.Thread的基础上进行封装 def auto_asset(node): re ...
 - 黄聪:WordPress 多站点建站教程(四):获取子站点相关信息(站点的注册时间,修改时间,总文章数,URL等)
		
1.获取子站点blogs表里面的内容信息 $blog_details = get_blog_details(1); echo 'Blog '.$blog_details->blog_id.' i ...
 - Android利用Handler异步获取子线程中的产生的值
		
本文首发于cartoon的博客 转载请注明出处:https://cartoonyu.github.io/cartoon-blog 近段时间有一个需求:在线获取图片并且显示在界面 ...
 - python 获取淘宝商品信息
		
python cookie 获取淘宝商品信息 # //get_goods_from_taobao import requests import re import xlsxwriter cok='' ...
 
随机推荐
- 特性Attribute 的使用
			
[IdentityAuthorize] public ActionResult Index() { return View("~/V ...
 - OSS.Social微信项目标准库介绍
			
经过本周的努力,昨晚终于完成OSS.Social微信项目的标准库支持,当前项目你已经可以同时在.net framework和.net core 中进行调用,调用方法也发生了部分变化,这里我简单分享下, ...
 - make: Nothing to be done for `all'
			
最近安装fastdfs,执行make.sh时,出现 Nothing to be done for `all' 在网上搜了一下,大部分是说 用 make clean 清除以前编译产生的目标文件. 我试 ...
 - 4G最快网速相当于30M宽带
			
[导读]据北京移动方面介绍,目前其4G网络的覆盖范围包括:东西北三环.南至两广路以内的地区:清华北大.国贸CBD及园博会等地区. 在4G年内发牌已成定局的背景下,各运营商都在加快布局,北京移动近期就推 ...
 - Spring源码解析三:IOC容器的依赖注入
			
一般情况下,依赖注入的过程是发生在用户第一次向容器索要Bean是触发的,而触发依赖注入的地方就是BeanFactory的getBean方法. 这里以DefaultListableBeanFactory ...
 - Linux内存中的 buffer 和 cache 到底是个什么东东?
			
Linux 中的 free 命令,会输出: total 总量 used 已使用 free 空闲 shared 共享内存 buffers cached 前面四项都比较好理解,一看我也就知道啥意思了.但 ...
 - 在Signalr的Hub中写方法实现与安卓的数据交互
			
简介: 实现数据实时刷新:SignalR 后台服务:.NET/WebAPI 为了减轻web的压力,将接口中接收数据的方法写到SignalR的Hub中 在此放一小段代码给自己加深下印象,博主有点健忘.. ...
 - centOS7 mini配置linux服务器(一)安装centOs7
			
1. 准备centos-7 (minni镜像) 官网地址http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-Minim ...
 - Apache Struts2存在S2-045
			
麻蛋的,批了老半天都找不到,还得谷歌 不扯蛋了,直接主题: Struts2 2.3.32 版本 下载地址:https://dist.apache.org/repos/dist/release/stru ...
 - 巧用*_his表记录操作历史
			
文章转载自「开发者圆桌」一个关于开发者入门.进阶.踩坑的微信公众号 许多OLTP应用的开发者都知道,一些重要的操作要记录操作历史,把操作前的数据备份到历史表,然后再执行相应的修改操作.这样可以获取某个 ...