thread termination

--HG--
branch : aspn
This commit is contained in:
baloan
2010-11-15 22:28:35 +01:00
parent 6092683f0a
commit 2a20e09944
4 changed files with 126 additions and 0 deletions

17
.project Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>aspn</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

10
.pydevproject Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/aspn/src</path>
</pydev_pathproperty>
</pydev_project>

74
src/killable_thread.py Normal file
View File

@@ -0,0 +1,74 @@
# http://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python
''' KillableThread '''
# system imports
import ctypes
import inspect
import threading
# definitions
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 )

25
src/stoppable_thread.py Normal file
View File

@@ -0,0 +1,25 @@
# http://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python
''' StoppableThread '''
# system imports
from threading import Event, Thread
# definitions
class StoppableThread(Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self):
super(StoppableThread, self).__init__()
self._stop = Event()
def stop(self):
self._stop.set()
def stopped(self):
return self._stop.isSet()