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