Re: How to "kill" orphaned threads at program exit
- From: BlueBird <phil@xxxxxxxxxxxxxxx>
- Date: Mon, 5 Jan 2009 03:05:32 -0800 (PST)
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
.
- Prev by Date: Re: why cannot assign to function call
- Next by Date: Re: why cannot assign to function call
- Previous by thread: Re: cx_Oracle issues
- Next by thread: fetch image
- Index(es):
Relevant Pages
|