kill thread

Mathieu Prevot mathieu.prevot at gmail.com
Sat Aug 9 14:39:22 EDT 2008


2008/8/8  <bockman at virgilio.it>:
> On 8 Ago, 10:03, "Mathieu Prevot" <mathieu.pre... at ens.fr> wrote:
>> 2008/8/8 Miki <miki.teb... at gmail.com>:
>>
>> > Hello,
>>
>> >> I have a threading.Thread class with a "for i in range(1,50)" loop
>> >> within. When it runs and I do ^C, I have the error [1] as many as
>> >> loops. I would like to catch this exception (and if possible do some
>> >> cleanup like in C pthreads) so the program finishes cleanly. Where and
>> >> how can I do this ? in __run__ ? __init__ ? a try/except stuff ?
>> > You can have a try/except KeyboardException around the thread code.
>>
>> > HTH,
>> > --
>> > Miki
>>
>> Of course, but I don't know where. I placed this inside loop, within
>> called functions from the loop, I still have the problem.
>>
>> Mathieu
>
> Try this:
>
>  loop_completed = True
>  for i in range(1,50):
>      try:
>         # your code here
>      except KeyboardException:
>         loop_completed = False
>         break # this breaks the loop
>  # end loop
>  if loop_completed:
>     # code to be executed in case of normal completion
>  else:
>     # code to be executed in case of interruption
>  # code to be executed in both cases

Thanks for answers. My code sheme was the following: main() starts 2
thread trees (threads of threads of ...) and some of these have "for"
loops. These loops needed to be as you recommended:

for ... :
  try:
    # instructions
  except KeyboardInterrupt:
    # cleaning instructions
    break

The problem with atexit.register is that is doesn't work in case of
system signals catches (http://tinyurl.com/6kdaba)

Thanks,
Mathieu

_____________________________________________
def main():
	query1 = Thread1
	batch1 = Thread2
	while True:
		try:
			#some code for updating / synchronize / etc threads
		except KeyboardInterrupt:
			try:
				query1.terminate()
				batch1.terminate()
			except:
				pass
			finally:
				break
_____________________________________________


I used also from http://sebulba.wikispaces.com/recipe+thread2
the following new Thread class:

_____________________________________________
import threading, inspect, ctypes

def _async_raise(tid, exctype):
    """raises the exception, performs cleanup if needed"""
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        # """if it returns a number greater than one, you're in trouble,
        # and you should call it again with exc=NULL to revert the effect"""
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
        raise SystemError("PyThreadState_SetAsyncExc failed")

class Thread(threading.Thread):
    def _get_my_tid(self):
        """determines this (self's) thread id"""
        if not self.isAlive():
            raise threading.ThreadError("the thread is not active")

        # do we have it cached?
        if hasattr(self, "_thread_id"):
            return self._thread_id

        # no, look for it in the _active dict
        for tid, tobj in threading._active.items():
            if tobj is self:
                self._thread_id = tid
                return tid

        raise AssertionError("could not determine the thread's id")

    def raise_exc(self, exctype):
        """raises the given exception type in the context of this thread"""
        _async_raise(self._get_my_tid(), exctype)

    def terminate(self):
        """raises SystemExit in the context of the given thread, which should
        cause the thread to exit silently (unless caught)"""
        self.raise_exc(SystemExit)
_____________________________________________



More information about the Python-list mailing list