Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-具有父线程处理子线程异常_Python_Multithreading_Exception_Parent Child_Watchdog - Fatal编程技术网

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()