Kill a thread in Python


C

C. Barnes

This code module allows you to kill threads. The
class KThread is a drop-in replacement for
threading.Thread. It adds the kill() method, which
should stop most threads in their tracks.

#
---------------------------------------------------------------------
# KThread.py: A killable Thread implementation.
#
---------------------------------------------------------------------

import sys
import trace
import threading

class KThread(threading.Thread):
"""A subclass of threading.Thread, with a kill()
method."""
def __init__(self, *args, **keywords):
threading.Thread.__init__(self, *args, **keywords)
self.killed = False

def start(self):
"""Start the thread."""
self.__run_backup = self.run
self.run = self.__run # Force the Thread to
install our trace.
threading.Thread.start(self)

def __run(self):
"""Hacked run function, which installs the
trace."""
sys.settrace(self.globaltrace)
self.__run_backup()
self.run = self.__run_backup

def globaltrace(self, frame, why, arg):
if why == 'call':
return self.localtrace
else:
return None

def localtrace(self, frame, why, arg):
if self.killed:
if why == 'line':
raise SystemExit()
return self.localtrace

def kill(self):
self.killed = True


------------------------------------------------------------------------
Example usage:
------------------------------------------------------------------------

This illustrates running a function in a separate
thread. The thread is
killed before the function finishes.

from KThread import *

def func():
print 'Function started'
for i in xrange(1000000):
pass
print 'Function finished'

A = KThread(target=func)
A.start()
for i in xrange(1000000):
pass
A.kill()

print 'End of main program'


Output:

Function started
End of main program


-----------------------------------------------------------------------
How It Works:
-----------------------------------------------------------------------

The KThread class works by installing a trace in the
thread. The trace
checks at every line of execution whether it should
terminate itself.
So it's possible to instantly kill any actively
executing Python code.
However, if your code hangs at a lower level than
Python, then the
thread will not actually be killed until the next
Python statement is
executed.

-----------------------------------------------------------------------
Considerations:
-----------------------------------------------------------------------

Certain IDEs may install their own threading trace
code, for debugging
purposes. This module is incompatible with those
IDEs.

Consider bugging the Python folks, until they give us
a thread kill
method. The code has already been written:

http://mail.python.org/pipermail/python-list/2003-February/148999.html


Regards,
Connelly Barnes





__________________________________
Do you Yahoo!?
Win a $20,000 Career Makeover at Yahoo! HotJobs
http://hotjobs.sweepstakes.yahoo.com/careermakeover
 
Ad

Advertisements

R

Roger Binns

C. Barnes said:
However, if your code hangs at a lower level than
Python, then the
thread will not actually be killed until the next
Python statement is
executed.

That is the usual case for me. My threads are blocked in calls
to read, accept or Queue.get().
Consider bugging the Python folks, until they give us
a thread kill
method. The code has already been written:

http://mail.python.org/pipermail/python-list/2003-February/148999.html

Looking through that patch I couldn't tell if it could
terminate a thread that was in native code. It seemed
to cause the kill to happen in the next bit of Python
bytecode interpretted.

Incidentally Java does have a thread kill method although
it is strongly recommended against using.

Roger
 
P

Peter Hansen

C. Barnes said:
This code module allows you to kill threads. The
class KThread is a drop-in replacement for
threading.Thread. It adds the kill() method, which
should stop most threads in their tracks.
def __run(self):
"""Hacked run function, which installs the
trace."""
sys.settrace(self.globaltrace)
self.__run_backup()
self.run = self.__run_backup

Although I'm usually against premature optimization, in this
case I have to point out the potentially *very* significant
impact of using the system tracing capability...

Also, this sort of "kill" is easily implemented on a special
case basis in real code, where you generally just want to check
at a high level whether the thread has been requested to die.
Doing it at each bytecode seems like overkill, unless you
tend to write lots of potentially endless loops at lower levels.

Having a thread stuck in external code is by far the most common
use case for this, I think, which this won't handle.

It's a nice example of a use of sys.settrace, however...

-Peter
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top