Python threading(多線程)


   threading模塊在較低級別thread模塊之上構建更高級別的線程接口。

 

一、threading模塊定義了以下函數和對象:

  threading.active_count()
    等同於threading.activeCount(),返回Thread當前活動的對象數。返回的計數等於返回的列表的長度enumerate()。

  threading.Condition()
    返回新條件變量對象的工廠函數。條件變量允許一個或多個線程等待,直到另一個線程通知它們。

  threading.current_thread()
    等同於currentThread(),返回當前Thread對象,對應於調用者的控制線程。如果未通過threading模塊創建調用者的控制線程,則返回具有有限功能的虛擬線程對象。

  threading.enumerate()
    返回Thread當前活動的所有對象的列表。該列表包括守護線程,由其創建的虛擬線程對象 current_thread()和主線程。它排除了尚未啟動的已終止線程和線程。

  threading.Event()
    返回新事件對象的工廠函數。事件管理一個標志,該標志可以使用該set()方法設置為true,並使用該方法重置為false clear()。該wait()方法將阻塞,直到該標志為真。

  class threading.local
    表示線程本地數據的類。線程局部數據是其值是線程特定的數據。要管理線程本地數據,只需創建一個local(或子類)實例並在其上存儲屬性。

  threading.Lock()
    返回新原始鎖定對象的工廠函數。一旦線程獲得它,后續嘗試獲取它就會阻塞,直到它被釋放; 任何線程都可以釋放它。

  threading.RLock()
    返回新的可重入鎖定對象的工廠函數。必須由獲取它的線程釋放可重入鎖。一旦線程獲得了可重入鎖,同一個線程可以再次獲取它而不會阻塞; 線程必須在每次獲取它時釋放一次。

  threading.Semaphore([ value] )
    返回新信號量對象的工廠函數。信號量管理一個計數器,表示release()呼叫數減去acquire()呼叫數 加上初始值。該acquire()方法在必要時阻止,直到它可以返回而不使計數器為負。如果沒有給出,則值默認為1。

  threading.BoundedSemaphore([ value] )
    返回新的有界信號量對象的工廠函數。有界信號量檢查以確保其當前值不超過其初始值。如果確實如此,ValueError則提出。在大多數情況下,信號量用於保護容量有限的資源。如果信號量被釋放太多次,則表明存在錯誤。如果沒有給出,則值默認為1。

  class threading.Thread
    表示控制線程的類。該類可以以有限的方式安全地進行子類化。

  class threading.Timer
    在指定的時間間隔過后執行函數的線程。

  threading.settrace(func
    為從threading模塊啟動的所有線程設置跟蹤功能。在調用sys.settrace()其run()方法之前,將為每個線程 傳遞 func。

  threading.setprofile(func
    為從threading模塊啟動的所有線程設置配置文件功能。在調用sys.setprofile()其run()方法之前,將為每個線程 傳遞 func。

  threading.stack_size([ size] )
    返回創建新線程時使用的線程堆棧大小。可選的 size參數指定用於后續創建的線程的堆棧大小,並且必須為0(使用平台或配置的默認值)或至少為32,768(32 KiB)的正整數值。

    如果未指定大小,則使用0。如果不支持更改線程堆棧大小,則引發ThreadError。如果指定的堆棧大小無效,則引發ValueError 且堆棧大小不被修改。32kB是目前支持的最小堆棧大小值,以保證解釋器本身有足夠的堆棧空間。

    請注意,某些平台可能對堆棧大小的值有特定限制,例如要求最小堆棧大小> 32kB或需要以系統內存頁面大小的倍數進行分配 - 應參考平台文檔以獲取更多信息(4kB頁面是常見的 ;在沒有更具體的信息的情況下,建議的方法是使用4096的倍數作為堆棧大小。

  exception threading.ThreadError
    針對各種與線程相關的錯誤引發。請注意,許多接口使用RuntimeError而不是ThreadError。

 

二、Thread Objects

  此類表示在單獨的控制線程中運行的活動,有兩種方法可以指定活動:

  一是將可調用對象傳遞給構造函數,二是通過覆蓋子類中的run()方法,但不要在子類中重寫其他方法,換句話說,只覆蓋此類的__init __()和run()方法。

  classthreading.Threadgroup = None,target = None,name = None,args =(),kwargs = {}

    應始終使用關鍵字參數調用此構造函數。參數是:

      group 應該None,在實現ThreadGroup類時保留用於將來的擴展。

      target 是run()方法調用的可調用對象。默認為None,意味着什么都沒有被調用。

      name 是線程名稱。默認情況下,唯一名稱由“Thread- N ” 形式構成,其中N是小十進制數。

      args 是目標調用的參數元組。默認為()。

      kwargs 是目標調用的關鍵字參數字典。默認為{}。

    如果子類重寫構造函數,則必須確保在對線程執行任何其他操作之前調用基類構造函數(Thread .__ init __())。

  start()
    啟動線程的活動。

    每個線程對象最多只能調用一次,它安排在一個單獨的控制線程中調用對象的 run()方法。

    如果在同一個線程對象上多次調用此方法,則會引發RuntimeError。

  run()
    表示線程活動的方法。

    你可以在子類中覆蓋此方法。 標准的 run()方法調用傳遞給對象構造函數的可調用對象作為目標參數,分別使用args和kwargs參數中的順序和關鍵字參數。

  join([ timeout] )
    等待線程終止,這將阻塞調用線程,直到調用其join()方法的線程終止,或者直到發生異常、超時。

    當timeout參數存在且非None時,它應該是一個浮點數,用於指定操作的超時(以秒為單位);反之當timeout參數不存在或為None時,操作將阻塞直到線程終止。

    由於join()總是返回None,你必須在join()之后調用isAlive()來判斷是否發生了超時,如果線程仍處於活動狀態,則join()調用超時。

    如果在線程啟動之前調用join(),則會引發RuntimeError。

  name()
    一個僅用於識別目的字符串,它沒有語義。 多個線程可以賦予相同的名稱,初始名稱由構造函數設置。

    getName()
    setName()

  ident

    該線程的標識符,如果線程尚未啟動,則為None,這是一個非零整數。當線程退出並創建另一個線程時,線程標識符可以被回收。 即使在線程退出后,該標識符也可用。

  is_alive()
    等同於isAlive(),返回線程是否存活。

    此方法在run()方法啟動之前返回True,直到run()方法終止之后。 模塊函數enumerate()返回所有活動線程的列表。

  daemon()
    一個布爾值,指示此線程是否為守護程序線程True 或False。 必須在調用start()之前設置它,否則引發RuntimeError。 它的初始值繼承自創建線程,主線程不是守護程序線程,因此在主線程中創建的所有線程都默認為daemon = False。

    isDaemon()
    setDaemon()

 

三、Lock Objects

  原始鎖是一種同步原語,在鎖定時不屬於特定線程。 在Python中,它是當前可用的最低級別同步原語,由線程擴展模塊直接實現。

  Lock.acquire([ blocking] )
    獲取鎖定,blocking或non-blocking。

    當blocking參數設置為True 時調用(默認值),阻塞直到解鎖,然后將其設置為鎖定並返回True。

    在將blocking參數設置為False的情況下調用時,請勿阻止。如果blocking設置為True的調用將阻塞,則立即返回False;否則,將Lock設置為鎖定並返回True。

  Lock.release()
    釋放鎖定。

    當Lock是鎖定時,將其重置為解鎖狀態,然后返回。如果阻止任何其他線程等待Lock解鎖,則只允許其中一個繼續執行。

    在未鎖定的Lock上調用時,會引發ThreadError。

    

四、RLock Objects

  線程會調用其acquire()方法來鎖定Lock,調用其release()方法來解鎖Lock,一旦線程擁有Lock它就會返回。

  acquire()/release()可以嵌套調用,只有最終的release()將Lock重置為unlocked並允許在acquire()中阻塞的另一個線程繼續進行。

  RLock.acquire([ blocking = 1 ] )
    獲取鎖定,blocking或non-blocking。

    在不帶參數的情況下調用:如果此線程已擁有鎖,則將遞歸級別遞增1,並立即返回。否則,如果另一個線程擁有該鎖,則阻塞直到鎖被解鎖。

    Lock解鎖后(不屬於任何線程),然后獲取所有權,將遞歸級別設置為1,然后返回。如果多個線程被阻塞等待Lock解鎖,則一次只能有一個線程獲取Lock的所有權。在這種情況下沒有返回值。

    在將blocking參數設置為true的情況下調用時,執行與不帶參數調用時相同的操作,並返回true。

    在將blocking參數設置為false的情況下調用時,請勿阻止。如果沒有參數的調用會阻塞,則立即返回false;否則,執行與不帶參數調用時相同的操作,並返回true。

  RLock.release()
    釋放鎖定,遞減遞歸級別。如果在遞減之后它為零,則將Lock重置為未鎖定,並且如果阻止任何其他線程等待Lock解鎖,則允許其中一個繼續進行。如果在遞減之后遞歸級別仍然非零,則Lock保持鎖定並由調用線程擁有。

    僅在調用線程擁有Lock時調用此方法。如果在未鎖定時調用此方法,則引發RuntimeError。

 

五、Condition Objects

  該類總是與某種鎖相關聯,默認情況下會創建一個,也可以傳入。

  該類具有acquire()和release()方法,這些方法調用相關鎖的相應方法。它還有一個wait()方法,以及notify()和notifyAll()方法,只有在調用線程獲得鎖定時才能調用這三個,否則會引發RuntimeError。

  class threading.Condition([ lock ] )
    如果給出lock參數且非None,則它必須是一個Lock 或RLock對象,並且它被用作底層鎖。否則,將創建一個RLock新對象並將其用作基礎鎖。

  acquire(* args )
    獲取底層鎖。此方法在底層鎖上調用相應的方法; 返回該方法所有值。

  release()
    釋放底層鎖。此方法在底層鎖上調用相應的方法; 沒有返回值。

  wait([timeout] )
    等到通知或直到發生超時。如果在調用此方法時調用線程尚未獲取鎖定,則引發RuntimeError。

    此方法釋放底層鎖,然后阻塞直到它被另一個線程中的相同條件變量的notify()或notifyAll()調用喚醒,或者直到發生超時。一旦被喚醒或超時,它就會重新獲得鎖定並返回。

    當timeout參數存在且非None時,它應該是一個浮點數,指定操作的超時(以秒為單位)。

    當底層鎖是一個RLock時,它不會使用其release()方法釋放,因為當遞歸多次獲取時,這實際上可能無法解鎖。相反,使用了RLock類的內部接口,即使多次遞歸獲取也能解鎖它。然后,在重新獲取鎖時,使用另一個內部接口來恢復遞歸級別。

  notify(n = 1 )
    默認情況下,喚醒一個等待此條件的線程。如果在調用此方法時調用線程尚未獲取鎖定, 則引發RuntimeError。

    此方法最多喚醒等待條件變量的n個線程,如果沒有線程在等待,那么這是一個無用操作。

  notify_all()
    等同於notifyAll(),喚醒符合條件的所有等待線程。此方法就像 notify(),但喚醒所有等待的線程而不是一個。如果在調用此方法時調用線程尚未獲取鎖定, 則引發RuntimeError。

# Consume one item
cv.acquire()
while not an_item_is_available():
    cv.wait()
get_an_available_item()
cv.release()

# Produce one item
cv.acquire()
make_an_item_available()
cv.notify()
cv.release()

 

六、Semaphore Objects

  Semaphore管理一個內部計數器,該計數器由每個acquire()調用遞減,並由每個release()調用遞增。 計數器永遠不會低於零,當acquire()發現它為零時,它會阻塞,等待其他線程調用release()。

  class threading.Semaphore([ value ] )
    可選參數給出內部計數器一個初始value; 它默認為1。如果給定的值小於0,則引發ValueError。

  acquire([ block] )
    獲取信號量。

    在不帶參數的情況下調用:如果內部計數器在輸入時大於零,則將其減1並立即返回。如果在進入時為零,則阻塞,等待其他線程調用 release()以使其大於零。

    這是通過適當的互鎖來完成的,這樣如果多個acquire()呼叫被阻止,它們 release()將完全喚醒其中一個。實現可以隨機選擇一個,因此不應該依賴被阻塞的線程被喚醒的順序。在這種情況下沒有返回值。

    當使用blocking設置為true 調用時,執行與不帶參數調用時相同的操作,並返回true。

    當阻塞設置為false 時調用,請勿阻止。如果沒有參數的調用會阻塞,則立即返回false; 否則,執行與不帶參數調用時相同的操作,並返回true。

  release()
    釋放信號量,將內部計數器遞增1。當它在進入時為零並且另一個線程正在等待它再次大於零時,喚醒該線程。

 

七、Event Objects

  可以使用set()方法將其標志設置為true,並使用clear()方法將其標志重置為false,wait()方法將阻塞,直到該標志為true。

  class threading.Event
    內部標志初始為false。

  is_set()
  isSet()
    當且僅當內部標志為真時返回true。

  set()
    將內部標志設置為true。等待它變為真的所有線程都被喚醒。wait()一旦標志為真,調用的線程將不會阻塞。

  clear()
    將內部標志重置為false。隨后,線程調用 wait()將阻塞,直到set()被調用以再次將內部標志設置為true。

  wait([ timeout] )
    阻止,直到內部標志為真。如果輸入時內部標志為真,則立即返回。否則,阻塞直到另一個線程調用 set()將標志設置為true,或者直到發生超時。

    當timeout參數存在且非None時,它應該是一個浮點數,指定操作的超時(以秒為單位)。

    此方法在退出時返回內部標志,因此它將始終返回True, 除非給定超時並且操作超時。

     

八、Timer Objects

   通過調用start()方法啟動計時器,通過調用cancel()方法可以停止計時器(在其動作開始之前)。

  class threading.Timer(interval,function,args = [],kwargs = {} )
    創建一個定時器,在經過間隔N秒后,將使用參數args和關鍵字參數kwargs運行函數。

  cancel()
    停止計時器,取消執行計時器的操作。這僅在定時器仍處於等待階段時才有效。

def hello():
    print "hello, world"

t = Timer(30.0, hello)
t.start()  # 30秒之后print

 

九、使用with語句

  此模塊提供的具有acquire()和 release()方法的所有對象都可以用作with 語句的上下文管理器。

  在輸入塊時將調用acquire()方法,並在退出塊時調用release()方法。

  目前Lock,RLock,Condition, Semaphore,和BoundedSemaphore 對象都可以用作 with聲明上下文管理。

import threading

some_rlock = threading.RLock()

with some_rlock:
  print "some_rlock is locked while this executes"

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM