Killing a thread
Antoon Pardon
apardon at forel.vub.ac.be
Mon Jun 12 05:17:32 EDT 2006
Op 2006-06-10, Carl J. Van Arsdall schreef <cvanarsdall at mvista.com>:
> Felipe Almeida Lessa wrote:
>> Em Sex, 2006-06-09 às 13:54 -0700, Manish Marathe escreveu:
>>
>>> On 6/9/06, Fredrik Lundh <fredrik at pythonware.com> wrote:
>>> Manish Marathe wrote:
>>>
>>> > I am creating threads using my self defined class which
>>> inherits the
>>> > threading.Thread class. I want to know how can I kill the
>>> threads which
>>> > are being created by the object of my self defined class.
>>>
>>> you cannot kill a thread "from the outside"; you have to
>>> design your
>>> thread tasks so they can kill themselves, when asked to do
>>> that.
>>>
>>> Thanks for the reply. So can a thread listen to an event i.e. can we
>>> send an event to the thread indicating to kill itself.
>>>
>>
>> A plain simple boolean flag will certainly do the job. For example
>>
>> def run(self):
>> self.running = True
>> while self.running:
>> blah()
>>
>> def stop(self):
>> self.running = False
>>
>>
> Well, this works if your threads are able to poll. If you had a thread
> doing lengthy IO you could end up waiting a long time until the thread
> gets an opportunity to kill itself.
>
> Are there any plans in the future to add the capability to kill threads
> from the outside?
There already is some capability, (if you mean from the outside
that one thread can kill another) However for the momemt it is
only available in the C API. But with the ctypes interface
(which will be available with the stdlib from version 2.5)
you can provide this functionality in python.
> Better yet, an interruptable thread so instead of
> using a polling loop you could send a DIE_THREAD_DIE signal or
> something. I think at present its not possible (or a really bad idea)
> to put signal handlers in threads. Anyone have thoughts on this?
It is indeed impossible to let a thread handle a signal. You can
set a handler in a thread but when a signal arrives.
But here is a class I toyed with, that can be used to throw
an exception in one thread from another. There are some
caveats however. It won't interupt C-calls. So if the
thread you want to raise the exception in, is in a C-extention,
the extention will have to finish before the exception will be
raised.
-----------------------------------------------------------------------
import ctypes
from time import sleep
SetAsyncExc = ctypes.pythonapi.PyThreadState_SetAsyncExc
class TimeOut(Exception):
pass
class Alarm(Exception):
pass
import threading
class Xthread(threading.Thread):
def start(self):
self.__original_run = self.run
self.run = self.__run
threading.Thread.start(self)
def __run(self):
self._thrd_id = threading._get_ident()
try:
self.__original_run()
finally:
self.run = self.__original_run
def throw(self, excpt):
Nr = SetAsyncExc(self._thrd_id, ctypes.py_object(excpt))
while Nr > 1:
SetAsyncExc(self._thrd_id, None)
sleep(0.1)
Nr = SetAsyncExc(self._thrd_id, ctypes.py_object(excpt))
def alarm(self, tm):
alrm = threading.Timer(tm, self.throw, (TimeOut,))
alrm.start()
return alrm
if __name__ == "__main__":
import os
from random import randint
class Continue(Xthread):
def run(self):
self.id = os.getpid()
print self.id, self._thrd_id, "Begin"
i = 0
try:
for _ in xrange(randint(0,20)):
for e in xrange(4 * 100000):
i = i + e
print self.id, self._thrd_id, "Finished"
except Alarm:
print self.id, self._thrd_id, "Interupted"
lst = [Continue() for _ in xrange(10)]
for T in lst:
T.start()
try:
sleep(10)
finally:
for T in lst:
T.throw(Alarm)
--
Antoon Pardon
More information about the Python-list
mailing list