1. 程式人生 > 程式設計 >python子執行緒退出及執行緒退出控制的程式碼

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

跑起來是沒有問題的,但是使用ctrl + c中斷的時候出問題了,主執行緒退出了,但子執行緒仍然執行。

於是在主執行緒增加了訊號處理的程式碼,收到sigint時改變子執行緒迴圈條件

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

這樣ctrl+c就可以退出了,但是疑惑的是,主執行緒退出程序不會退出嗎?

知識點擴充套件Python執行緒退出控制

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,# 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子執行緒退出及執行緒退出控制的程式碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對我們網站的支援!
如果你覺得本文對你有幫助,歡迎轉載,煩請註明出處,謝謝!