2008/8/8 <[EMAIL PROTECTED]>: > On 8 Ago, 10:03, "Mathieu Prevot" <[EMAIL PROTECTED]> wrote: >> 2008/8/8 Miki <[EMAIL PROTECTED]>: >> >> > 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) _____________________________________________ -- http://mail.python.org/mailman/listinfo/python-list