Re: How to "kill" orphaned threads at program exit



On Dec 28 2008, 6:33 pm, "Giampaolo Rodola'" <gne...@xxxxxxxxx> wrote:
Hi,
I know that it's not possible to "kill" threads but I'm wondering if
does exist some workaround for my problem.
I have a test suite which does a massive usage of threads.
Sometimes happens that one test fails, the test suite keeps running
until the end, and when it's finished the program hangs on and the
only way to stop is to kill it manually.
I noticed that, at the end of the program, I can call
threading.enumerate() and see the pending thread objects:


Hi,

The way I handle it is to make sure that after each test, the thread
count has returned to what I expect.

It is possible to kill a thread if it's not blocked on a system call.
It's highly unrecommended for standard usage but your use case exactly
the one where the ability to kill a thread is very useful.

I use the following code, which I borrowed to the Python Cook book
somewhere:

def _async_raise(tid, exctype):
'''Raises an exception in the threads with id tid'''
if not inspect.isclass(exctype):
raise TypeError("Only types can be raised (not instances)")
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
ctypes.py_object(exctype))
if res == 0:
raise ValueError("invalid thread id")
elif res != 1:
# """if it returns a number greater than one, you're in
trouble,
# and you should call it again with exc=NULL to revert the
effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
raise SystemError("PyThreadState_SetAsyncExc failed")


class ThreadWithExc(threading.Thread):
'''A thread class that supports raising exception in the thread
from another thread.
'''
def _get_my_tid(self):
"""determines this (self's) thread id

CAREFUL : this function is executed in the context of the
caller thread,
to get the identity of the thread represented by this
instance.
"""
if not self.isAlive():
raise threading.ThreadError("the thread is not active")

# do we have it cached?
if hasattr(self, "_thread_id"):
return self._thread_id

# no, look for it in the _active dict
for tid, tobj in threading._active.items():
if tobj is self:
self._thread_id = tid
return tid

# TODO : in python 2.6, there's a simpler way to do :
self.ident ...

raise AssertionError("could not determine the thread's id")

def raiseExc(self, exctype):
"""Raises the given exception type in the context of this
thread.

If the thread is busy in a system call (time.sleep(),
socket.accept(), ...) the exception
is simply ignored.

If you are sure that your exception should terminate the
thread, one way to ensure that
it works is:
t = ThreadWithExc( ... )
...
t.raiseExc( SomeException )
while t.isAlive():
time.sleep( 0.1 )
t.raiseExc( SomeException )

If the exception is to be caught by the thread, you need a way
to check that your
thread has caught it.

CAREFUL : this function is executed in the context of the
caller thread,
to raise an excpetion in the context of the thread represented
by this instance.
"""
_async_raise( self._get_my_tid(), exctype )



cheers,

Philippe
.



Relevant Pages

  • Re: Fold A-Qs here?
    ... >> kill of $16, I had the leg up and A-Qs to the right of the CO. ... >> your raise with weak holdings. ... If I lose I have to, well, loose. ... Is a pre-flop fold here ...
    (rec.gambling.poker)
  • Re: Adjusting a services "CanStop" on the fly?
    ... > I was also unsuccessfull at navigating the windows station to deturmine ... determine who is trying to kill the service. ... what happens if the OnStop method throws an exception? ... RegisterServiceCtrlHandlerEx from you... ...
    (microsoft.public.dotnet.languages.vb)
  • program behavior differs when tracing function is set
    ... raise Exception, 'Kill them all!!!' ... def trace(event, file, line, id, binding, klass) ...
    (comp.lang.ruby)
  • RE: how to run an arbitrary function with timeout?
    ... > i'm building a test suite on top of unittest, ... > return either the value or raise an exception if it times ... RunWithTimeout also returns, at the point it raises its exception. ... Best I can guess, you're expecting something that can't happen, but I'm not ...
    (comp.lang.python)
  • how to run an arbitrary function with timeout?
    ... i'm building a test suite on top of unittest, ... return either the value or raise an exception if it times ... from time import sleep ... def RunWithTimeout(func, args, timeout): ...
    (comp.lang.python)