Python-具有父线程处理子线程异常
有没有办法让产生新线程的父线程捕获产生的线程异常?下面是我试图完成的一个真实的基本例子。当引发异常时,它应该停止计数,但我不知道如何捕获它。异常是线程安全的吗?我希望能够使用Python-具有父线程处理子线程异常,python,multithreading,exception,parent-child,watchdog,Python,Multithreading,Exception,Parent Child,Watchdog,有没有办法让产生新线程的父线程捕获产生的线程异常?下面是我试图完成的一个真实的基本例子。当引发异常时,它应该停止计数,但我不知道如何捕获它。异常是线程安全的吗?我希望能够使用子流程模块,但我一直在使用Python2.3,不知道还有什么其他方法可以做到这一点。是否可能使用线程模块 import time import thread def test(): try: test = thread.start_new_thread(watchdog, (5,))
子流程
模块,但我一直在使用Python2.3,不知道还有什么其他方法可以做到这一点。是否可能使用线程
模块
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调用
坚持使用Python 2.3
Python 2.3现在已经有10年的历史了。你为什么还在用它
可能使用线程模块
无论如何,您都应该使用线程
不过,你可能对这个问题的想法是错误的。您可能应该创建一些类并重新思考解决问题的方法
此外,如果您正在创建一个看门狗,那么将它与您正在做的事情放在同一个过程中可能没有多大意义。time.sleep()是一个常规python
异常无论如何都不会取消的系统调用。如果您真正想做的是传递/处理异常,那么我认为您不想使用子进程,因为父进程只能“看到”状态代码(和输出)由子进程生成-只有在子进程中发生即时和灾难性故障时,才会在父进程中“重新引发”异常:
而且(如果您试图传递/处理异常,同样)我也不确定您是否需要线程。毕竟,异常的要点(IMO)是拥有一些可以“由调用方”(在一个try块内)处理的东西,或者如果不处理,可以提供有意义的回溯信息(调用序列)。这两种想法都不适用于一条线中的“扔”和另一条线中的“抓”
如果您的真正目标是让一条逻辑“超时”另一条,那么我认为您的“看门狗”是一个单独的进程是有意义的——要么是一个“父”进程,监视“子”进程的输出(以及经过的时间),要么是一个“对等”进程,“监视”被监视进程的日志行和/或数据库更新(以及时钟). 在这两种情况下,例外情况都不是特别相关的。我建议大家看看Alex Martelli对这个问题的回答:
这个问题还有几个与您的问题相关的好答案:
为什么不做这样的事情呢
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()
我知道您一直在使用Python 2.3,但如果您只能(非常)适度地升级到Python 2.4,那么您可以利用这种更直接的方法,从Yaroslav Bulatov给出的答案复制到关于运行带超时的外部命令的问题(推荐阅读):
这是一个父进程超时子进程的示例,如我在前面的回答中所述。可能会重复您试图实现的目标,看起来您希望从子线程向父线程发送某个事件的信号?或者你真的想传递异常吗?我正在尝试终止一个os.system
调用,如果它需要很长的时间,很可能不是正确的方法。我一直在使用2.3,因为这是PSS/E rev 30 python模块编译的内容,这就是我们使用的内容。如果os.system
调用由于某种原因挂起,我正在尝试终止它。因此,我试图在生成的看门狗返回异常时杀死父进程。除了os.system
或os.popen
之外,还有什么东西我可以调用,它将立即在Python中继续运行,我可以在中保持循环,直到超时或完成?你仍然想得太具体了。告诉我们你想完成什么如果某个os.system调用因某种原因挂起,我将尝试终止它。
您将很难找到真正的解决方案。你的问题很可能是系统调用挂起,而不是你不能中断它。或者你可以这样想(顺便说一句,这不是Python特有的)——如果有一个系统调用由于某种原因而在你的控制之外“挂起”,那么你就让父进程成为“看门狗”,并让子进程实际运行系统调用。然后,父进程可以以各种方式监视子进程——例如,子进程可以向父进程监视的STDOUT写入“heartbeat”消息(比如每30秒一次),父进程可以决定何时“挂起”子进程,并在必要时将其杀死。Falmari——很简单,我调用的是一个非python程序(在本例中,计数为10.exe)我的Python程序必须等待它的继续运行。现在考虑代替CurtTyto10,它是CuthtTotox号,并且数字是无穷大的。我想要一个看门狗,它查看非Python程序是否占用了太长时间并停止它,然后引发异常。thip。ommand不存在。但是os.kill确实存在,并且运行良好。演示如何让父级执行带超时的系统调用的几个答案,这似乎是您真正想要实现的。尽管使用子进程
模块会很奇妙,但我不能,因为正如我在原始帖子中所述,我一直在使用2.3.我试图找到一种解决方法,但在我能够使用python 2.4或更高版本之前,我似乎无法找到。到目前为止,我正在使用的程序所使用的模块是在2.3中编译的,在2.4中无法工作
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()