开发者

Python - Have parent thread handle child threads Exception

Is there a way to have the parent that spawned a new thread catch the spawned threads exception? Below is a real basic example of what I am trying to accomplish. It should stop counting when Exception is raised, but I don't know how to catch it. Are exceptions thread safe? I would love to be able to use the Subprocess module, but I am stuck using Python 2.3 and am not sure how else to do this. Possibly using the threading module?

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

UPDATE

My original code was a little misleading. It am really looking for something more like this:

开发者_运维问答
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()

I am trying to create a watchdog to kill the os.system call if the program hangs up for some reason.


Why not something like this

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

This will stop the entire process. Another thing you could do is to start os.system in a different thread, then countdown and then kill that thread. Something like this,

def system_call():
    os.system('count_to_10.exe')

system_thread = thread.start_new_thread(system_call)
time.sleep(timeout)
system_thread.kill()


stuck using Python 2.3

Python 2.3 is like 10 years old now. Why are you still using it?

Possibly using the threading module

You should be using threading anyway.

You are probably thinking about the problem wrong though. You should probably create some classes and rethink the approach to your problem.

Also if you're creating a watchdog, it probably doesn't make much sense to have it in the same process as what you're doing. time.sleep() is a system call that a regular python Exception won't cancel anyway.


If what you're really trying to do is pass/handle an exception then I don't think you want to use a Subprocess, since the parent process can only "see" the status code (and output) produced by the child process - only in cases of immediate & catastrophic failure in the child process does an exception get "re-raised" in the parent: http://docs.python.org/library/subprocess.html#exceptions.

And (again if you're trying to pass/handle an exception) I'm not sure you want threads, either. After all, the whole point (IMO) of exceptions is to have something which can either be handled "by the caller" (inside a try block) or can provide meaningful backtrace information (the call sequence) if not handled. Neither idea really works with "throw" in one thread and "catch" in another.

If your real goal is to have one piece of logic "time out" another one, then I think it makes sense for your "watchdog" to be a separate process - either a "parent" that monitors output from a "child" (as well as time elapsed), or a "peer" that "watches" something like log lines and/or DB updates by the monitored process (as well as the clock). In neither case are exceptions particularly relevant. And I recommend taking a look at Alex Martelli's answer to this question: Using module 'subprocess' with timeout

This question also has a couple of good answers that are relevant to your question: Catch a thread's exception in the caller thread in Python


I know you're stuck using Python 2.3, but if you could only make the (very) modest advancement to Python 2.4 then you could take advantage of this more straightforward approach, copied from an answer given by Yaroslav Bulatov to a question (recommended reading) about running an external command with timeout: 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()

This is an example of a parent process timing out a child process, as mentioned in my earlier answer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜