這篇文章主要介紹了python子線程退出及線程退出控制的代碼,具有一定的參考借鑑價值,需要的朋友可以參考下
下面通過代碼給大家介紹python子線程退出問題,具體內容如下所示:
def thread_func():
while True:
#do something
#do something
#do something
t=threading.Thread(target = thread_func)
t.start()
# main thread do something
# main thread do something
# main thread do something
我是一名python開發工程師,整理了一套python的學習資料,從基礎的python腳本到web開發、爬蟲、
數據分析、數據可視化、機器學習、面試真題等。想要的可以進羣:688244617免費領取
於是在主線程增加了信號處理的代碼,收到sigint時改變子線程循環條件跑起來是沒有問題的,但是使用ctrl + c中斷的時候出問題了,主線程退出了,但子線程仍然運行。
loop = True
def thread_func():
while loop:
#do something
#do something
#do something
t=threading.Thread(target = thread_func)
t.start()
# ctrl+c時,改變loop爲False
def handler(signum, frame):
global loop
loop = False
t.join()
exit(0)
signal(SIGINT, handler)
# main thread do something
# main thread do something
# main thread do something
知識點擴展Python線程退出控制這樣ctrl+c就可以退出了,但是疑惑的是,主線程退出進程不會退出嗎?
ctypes模塊控制線程退出
Python中threading模塊並沒有設計線程退出的機制,原因是不正常的線程退出可能會引發意想不到的後果。
例如:
線程正在持有一個必須正確釋放的關鍵資源,鎖。
線程創建的子線程,同時也將被殺掉。
管理自己的線程,最好的處理方式是擁有一個請求退出標誌,這樣每個線程依據一定的時間間隔檢查規則,看是不是需要退出。
例如下面的代碼:
import threading
class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self):
super(StoppableThread, self).__init__()
self._stop_event = threading.Event()
def stop(self):
self._stop_event.set()
def stopped(self):
return self._stop_event.is_set()
然而,可能會出現確實想要殺掉線程的情況,例如你正在封裝一個外部庫,它會忙於長時間調用,而你想中斷它。這段代碼裏面,線程應該定期檢查停止標誌,在退出的時候,可以調用stop()函數,並且使用join()函數來等待線程的退出。
Python線程可以拋出異常來結束:
傳參分別是線程id號和退出標識
def _async_raise(tid, exctype):
'''Raises an exception in the threads with id tid'''
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")
簡化後,以上代碼可以應用在實際使用中來進行線程中斷,例如檢測到線程運行時常超過本身可以忍受的範圍。如果線程在python解釋器外運行時,它將不會捕獲中斷,即拋出異常後,不能對線程進行中斷。
def _async_raise(tid, exctype):
"""raises the exception, performs cleanup if needed"""
tid = ctypes.c_long(tid)
if not inspect.isclass(exctype):
exctype = type(exctype)
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, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
def stop_thread(thread):
_async_raise(thread.ident, SystemExit)
以上所述是小編給大家介紹的python子線程退出及線程退出控制的代碼,覺得文章還不錯的話不妨點個贊,有任何建議或看法歡迎大家在評論區分享討論!