How to force a thread to stop
Jean-Paul Calderone
exarkun at divmod.com
Thu Jul 27 08:59:31 EDT 2006
On Thu, 27 Jul 2006 02:30:03 -0500, Nick Craig-Wood <nick at craig-wood.com> wrote:
>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.
No, it has a method for raising an exception. This isn't quite the
same as a method for killing a thread. Also, this has been mentioned
in this thread before. Unfortunately:
import os, threading, time, ctypes
class ThreadKilledError(Exception):
pass
_PyThreadState_SetAsyncExc = ctypes.pythonapi.PyThreadState_SetAsyncExc
_c_ThreadKilledError = ctypes.py_object(ThreadKilledError)
def timeSleep():
time.sleep(100)
def childSleep():
os.system("sleep 100") # time.sleep(100)
def catchException():
while 1:
try:
while 1:
time.sleep(0.0)
except Exception, e:
print 'Not exiting because of', e
class KillableThread(threading.Thread):
"""
Show how to kill a thread -- almost
"""
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()
try:
return threading.Thread.run(self)
except Exception, e:
print 'Exiting', e
def main():
threads = []
for f in timeSleep, childSleep, catchException:
t = KillableThread(target=f)
t.start()
threads.append(t)
time.sleep(1)
for t in threads:
print 'Killing', t
t.kill()
for t in threads:
print 'Joining', t
t.join()
if __name__ == '__main__':
main()
Jean-Paul
More information about the Python-list
mailing list