[Python]获取子线程异常信息
2023-02-18 16:47:25 时间
起因
今天在写东西的时候,用到了多线程。遇到了个问题:
子线程的异常,在父线程中无法捕获。
解决
问题代码
问题代码示例代码如下:
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都不熟也能跑通AI人脸识别?“隐藏Boss”竟是它!
- 探究Python源码,终于弄懂了字符串驻留技术
- Python进阶丨如何创建你的第一个Python元类?
- 终于搞懂了Python模块之间的相互引用问题
- Python 基于xml.etree.ElementTree实现XML对比
- 手把手带你入门加密算法的Python实现
- Python基础之网络编程:7、网络并发编程理论与实操(三)
- Python基础之网络编程:6、网络并发编程理论与实操(二)
- Python基础之网络编程:5、网络并发编程理论与实操(一)
- Python基础之网络编程:4、黏包及解决办法
- Python基础之网络编程:3、socket模块
- Python基础之网络编程:2、OSI七层协议
- Python基础之网络编程:1、C/S架构和B/S架构
- Python基础阶段总结:ATM项目实战
- Python基础之模块:7、项目开发流程和项目需求分析及软件开发目录
- Python基础之模块:6、hashlib模块 subprocess模块 logging模块
- Python基础之模块:5、 第三方模块 requests模块 openpyxl模块
- Python基础之模块:4、正则表达式和re模块
- Python基础之模块:2、包的使用和软件开发目录规范及常用内置模块
- Python基础之模块:1、模块的导入和使用