有没有办法让生成新线程的父级捕获生成的线程异常?以下是我想要完成的一个真实的基本示例。当引发Exception时它应该停止计数,但我不知道如何捕获它。异常线程安全吗?我希望能够使用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调用。
答案 0 :(得分:2)
坚持使用Python 2.3
Python 2.3现在已经10年了。你为什么还在使用它?
可能使用穿线模块
无论如何你应该使用线程。
你可能正在考虑这个问题。您应该创建一些类并重新考虑解决问题的方法。
另外,如果您正在创建一个监视程序,那么将它与您正在执行的程序放在同一个进程中可能没什么意义。 time.sleep()是一个系统调用,普通的python Exception
无论如何都不会取消。
答案 1 :(得分:2)
如果您真正想要做的是传递/处理异常,那么我认为您不想使用Subprocess,因为父进程只能“看到”由该进程生成的状态代码(和输出)儿童过程 - 仅限于直接和子进程中的灾难性故障会在父进程中“重新引发”异常:http://docs.python.org/library/subprocess.html#exceptions。
(再次,如果你试图传递/处理异常)我也不确定你是否想要线程。毕竟,异常的全部要点(IMO)是可以“由调用者”(在try块内)处理或者可以提供有意义的回溯信息(调用序列) 未处理。这两种想法都不能在一个线程中“抛出”而在另一个线程中“捕获”。
如果你的真正目标是让一个逻辑“超时”另一个逻辑,那么我认为你的“看门狗”是一个独立的过程是有意义的 - 要么是一个监视“孩子”输出的“父母” “(以及经过的时间),或”监视“受监视进程(以及时钟)的日志行和/或数据库更新之类的”对等“。两种情况都不是特别相关的例外。我建议看一下Alex Martelli对这个问题的回答:Using module 'subprocess' with timeout
这个问题也有几个与你的问题相关的好答案: Catch a thread's exception in the caller thread in Python
答案 2 :(得分:2)
为什么不这样呢
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()
答案 3 :(得分:1)
我知道你使用的是Python 2.3,但是如果你只能对Python 2.4进行(非常)适度的推进那么你可以利用这种更简单的方法,从Yaroslav Bulatov给出的答案复制到一个问题(推荐阅读)关于使用超时运行外部命令:Python, Popen and select - waiting for a process to terminate or a timeout
from threading import Timer
from subprocess import Popen, PIPE
def kill_proc():
proc.kill()
proc = Popen("count_to_10.exe", shell=True)
t = Timer(60, kill_proc)
t.start()
proc.wait()
这是父进程超时子进程的示例,如我之前的回答中所述。