How to force a thread to stop
Nick Craig-Wood
nick at craig-wood.com
Thu Jul 27 03:30:03 EDT 2006
bryanjugglercryptographer at yahoo.com <bryanjugglercryptographer at yahoo.com> wrote:
> Hans wrote:
> > Is there a way that the program that created and started a thread also stops
> > it.
> > (My usage is a time-out).
> >
> > E.g.
> >
> > thread = threading.Thread(target=Loop.testLoop)
> > thread.start() # This thread is expected to finish within a second
> > thread.join(2) # Or time.sleep(2) ?
>
> No, Python has no threadicide method
Actually it does in the C API, but it isn't exported to python.
ctypes can fix that though.
> and its absence is not an oversight. Threads often have important
> business left to do, such as releasing locks on shared data; killing
> them at arbitrary times tends to leave the system in an inconsistent
> state.
Here is a demo of how to kill threads in python in a cross platform
way. It requires ctypes. Not sure I'd use the code in production but
it does work...
"""
How to kill a thread demo
"""
import threading
import time
import ctypes
class ThreadKilledError(Exception): pass
_PyThreadState_SetAsyncExc = ctypes.pythonapi.PyThreadState_SetAsyncExc
_c_ThreadKilledError = ctypes.py_object(ThreadKilledError)
def _do_stuff(t):
"""Busyish wait for t seconds. Just sleeping delays the exeptions in the example"""
start = time.time()
while time.time() - start < t:
time.sleep(0.01)
class KillableThread(threading.Thread):
"""
Show how to kill a thread
"""
def __init__(self, name="thread", *args, **kwargs):
threading.Thread.__init__(self, *args, **kwargs)
self.name = name
print "Starting %s" % self.name
def kill(self):
"""Kill this thread"""
print "Killing %s" % self.name
_PyThreadState_SetAsyncExc(self.id, _c_ThreadKilledError)
def run(self):
self.id = threading._get_ident()
while 1:
print "Thread %s running" % self.name
_do_stuff(1.0)
if __name__ == "__main__":
thread1 = KillableThread(name="thread1")
thread1.start()
_do_stuff(0.5)
thread2 = KillableThread(name="thread2")
thread2.start()
_do_stuff(2.0)
thread1.kill()
thread1.join()
_do_stuff(2.0)
thread2.kill()
thread2.join()
print "Done"
--
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick
More information about the Python-list
mailing list