Python - 让父线程处理子线程的异常
有没有办法让创建新线程的父线程能够捕捉到这个新线程的异常?下面是我想实现的一个非常简单的例子。当出现异常时,它应该停止计数,但我不知道怎么去捕捉这个异常。异常是线程安全的吗?我很想使用 Subprocess
模块,但我现在只能用 Python 2.3,不知道还有什么其他方法可以做到。也许可以使用 threading
模块?
import time
import thread
def test():
try:
test = thread.start_new_thread(watchdog, (5,))
count(10)
except:
print('Stopped Counting')
def count(num):
for i in range(num):
print i
time.sleep(1)
def watchdog(timeout):
time.sleep(timeout)
raise Exception('Ran out of time')
if __name__ == '__main__':
test()
更新
我最初的代码有点误导。我其实想要的是这样的:
import time
import thread
import os
def test():
try:
test = thread.start_new_thread(watchdog, (5,))
os.system('count_to_10.exe')
except:
print('Stopped Counting')
def watchdog(timeout):
time.sleep(timeout)
raise Exception('Ran out of time')
if __name__ == '__main__':
test()
我想创建一个监视程序,如果程序因为某种原因卡住了,就终止 os.system
的调用。
4 个回答
如果你真正想做的是处理异常,那么我觉得你不应该使用子进程。因为父进程只能看到子进程返回的状态码和输出,只有在子进程发生严重错误时,异常才会在父进程中被“重新抛出”:http://docs.python.org/library/subprocess.html#exceptions。
而且(如果你是想处理异常的话),我也不确定你需要使用线程。毕竟,我认为异常的主要目的就是让调用者可以处理它(在一个try块中),或者如果没有处理的话,可以提供有意义的回溯信息(调用顺序)。在一个线程中“抛出”异常而在另一个线程中“捕获”,这两种方式都不太适用。
如果你真正的目标是让一段逻辑“超时”另一段逻辑,那么我觉得让你的“监视者”成为一个独立的进程是有意义的——可以是一个“父进程”,监控“子进程”的输出和经过的时间,或者是一个“平行进程”,监控被监控进程的日志行和/或数据库更新(以及时间)。在这两种情况下,异常并不是特别相关。我建议你看看Alex Martelli对这个问题的回答:使用模块'subprocess'与超时
这个问题还有几个不错的答案,与你的问题相关: 在Python中捕获线程的异常到调用线程
卡在使用 Python 2.3
Python 2.3 现在差不多有十年了。你为什么还在用它呢?
可能是在用 threading 模块
其实你应该使用 threading 模块。
不过你可能对问题的理解有点偏差。你应该考虑创建一些类,重新思考一下你的问题解决方法。
另外,如果你在做一个监控程序,把它和你正在做的事情放在同一个进程里可能没什么意义。因为 time.sleep() 是一个系统调用,普通的 Python Exception
是无法取消它的。
为什么不试试这样做呢
def test():
def exeption_cb():
os._exit()
test = thread.start_new_thread(watchdog, (5, exception_cb))
os.system('count_to_10.exe')
print('Stopped Counting')
def watchdog(timeout, callback):
time.sleep(timeout)
callback()
这样做会停止整个过程。你还可以选择在一个不同的线程中启动os.system,然后进行倒计时,最后再结束那个线程。可以这样做,
def system_call():
os.system('count_to_10.exe')
system_thread = thread.start_new_thread(system_call)
time.sleep(timeout)
system_thread.kill()