欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python子線程退出及線程退出控制的代碼

 更新時(shí)間:2019年10月16日 10:29:59   作者:嗯啊哉  
這篇文章主要介紹了python子線程退出及線程退出控制的代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

下面通過(guò)代碼給大家介紹python子線程退出問(wèn)題,具體內(nèi)容如下所示:

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

跑起來(lái)是沒有問(wèn)題的,但是使用ctrl + c中斷的時(shí)候出問(wèn)題了,主線程退出了,但子線程仍然運(yùn)行。

于是在主線程增加了信號(hào)處理的代碼,收到sigint時(shí)改變子線程循環(huán)條件

loop = True
def thread_func():
  while loop:
      #do something
      #do something
      #do something
t=threading.Thread(target = thread_func)
t.start()
# ctrl+c時(shí),改變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就可以退出了,但是疑惑的是,主線程退出進(jìn)程不會(huì)退出嗎?

知識(shí)點(diǎn)擴(kuò)展Python線程退出控制

ctypes模塊控制線程退出

Python中threading模塊并沒有設(shè)計(jì)線程退出的機(jī)制,原因是不正常的線程退出可能會(huì)引發(fā)意想不到的后果。

例如:

線程正在持有一個(gè)必須正確釋放的關(guān)鍵資源,鎖。

線程創(chuàng)建的子線程,同時(shí)也將被殺掉。

管理自己的線程,最好的處理方式是擁有一個(gè)請(qǐng)求退出標(biāo)志,這樣每個(gè)線程依據(jù)一定的時(shí)間間隔檢查規(guī)則,看是不是需要退出。

例如下面的代碼:

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()

這段代碼里面,線程應(yīng)該定期檢查停止標(biāo)志,在退出的時(shí)候,可以調(diào)用stop()函數(shù),并且使用join()函數(shù)來(lái)等待線程的退出。

然而,可能會(huì)出現(xiàn)確實(shí)想要?dú)⒌艟€程的情況,例如你正在封裝一個(gè)外部庫(kù),它會(huì)忙于長(zhǎng)時(shí)間調(diào)用,而你想中斷它。

Python線程可以拋出異常來(lái)結(jié)束:

傳參分別是線程id號(hào)和退出標(biāo)識(shí)

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解釋器外運(yùn)行時(shí),它將不會(huì)捕獲中斷,即拋出異常后,不能對(duì)線程進(jìn)行中斷。

簡(jiǎn)化后,以上代碼可以應(yīng)用在實(shí)際使用中來(lái)進(jìn)行線程中斷,例如檢測(cè)到線程運(yùn)行時(shí)常超過(guò)本身可以忍受的范圍。

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)

總結(jié)

以上所述是小編給大家介紹的python子線程退出及線程退出控制的代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

最新評(píng)論