python子线程退出及线程退出控制的代码
下面通过代码给大家介绍python子线程退出问题,具体内容如下所示:
defthread_func(): whileTrue: #dosomething #dosomething #dosomething t=threading.Thread(target=thread_func) t.start() #mainthreaddosomething #mainthreaddosomething #mainthreaddosomething
跑起来是没有问题的,但是使用ctrl+c中断的时候出问题了,主线程退出了,但子线程仍然运行。
于是在主线程增加了信号处理的代码,收到sigint时改变子线程循环条件
loop=True defthread_func(): whileloop: #dosomething #dosomething #dosomething t=threading.Thread(target=thread_func) t.start() #ctrl+c时,改变loop为False defhandler(signum,frame): globalloop loop=False t.join() exit(0) signal(SIGINT,handler) #mainthreaddosomething #mainthreaddosomething #mainthreaddosomething
这样ctrl+c就可以退出了,但是疑惑的是,主线程退出进程不会退出吗?
知识点扩展Python线程退出控制
ctypes模块控制线程退出
Python中threading模块并没有设计线程退出的机制,原因是不正常的线程退出可能会引发意想不到的后果。
例如:
线程正在持有一个必须正确释放的关键资源,锁。
线程创建的子线程,同时也将被杀掉。
管理自己的线程,最好的处理方式是拥有一个请求退出标志,这样每个线程依据一定的时间间隔检查规则,看是不是需要退出。
例如下面的代码:
importthreading classStoppableThread(threading.Thread): """Threadclasswithastop()method.Thethreaditselfhastocheck regularlyforthestopped()condition.""" def__init__(self): super(StoppableThread,self).__init__() self._stop_event=threading.Event() defstop(self): self._stop_event.set() defstopped(self): returnself._stop_event.is_set()
这段代码里面,线程应该定期检查停止标志,在退出的时候,可以调用stop()函数,并且使用join()函数来等待线程的退出。
然而,可能会出现确实想要杀掉线程的情况,例如你正在封装一个外部库,它会忙于长时间调用,而你想中断它。
Python线程可以抛出异常来结束:
传参分别是线程id号和退出标识
def_async_raise(tid,exctype): '''Raisesanexceptioninthethreadswithidtid''' ifnotinspect.isclass(exctype): raiseTypeError("Onlytypescanberaised(notinstances)") res=ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype)) ifres==0: raiseValueError("invalidthreadid") elifres!=1: #"ifitreturnsanumbergreaterthanone,you'reintrouble, #andyoushouldcallitagainwithexc=NULLtoreverttheeffect" ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,0) raiseSystemError("PyThreadState_SetAsyncExcfailed")
如果线程在python解释器外运行时,它将不会捕获中断,即抛出异常后,不能对线程进行中断。
简化后,以上代码可以应用在实际使用中来进行线程中断,例如检测到线程运行时常超过本身可以忍受的范围。
def_async_raise(tid,exctype): """raisestheexception,performscleanupifneeded""" tid=ctypes.c_long(tid) ifnotinspect.isclass(exctype): exctype=type(exctype) res=ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,ctypes.py_object(exctype)) ifres==0: raiseValueError("invalidthreadid") elifres!=1: #"""ifitreturnsanumbergreaterthanone,you'reintrouble, #andyoushouldcallitagainwithexc=NULLtoreverttheeffect""" ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,None) raiseSystemError("PyThreadState_SetAsyncExcfailed") defstop_thread(thread): _async_raise(thread.ident,SystemExit)
总结
以上所述是小编给大家介绍的python子线程退出及线程退出控制的代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!