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

Python線程threading模塊用法詳解

 更新時(shí)間:2020年02月26日 11:49:44   作者:luckycyong  
這篇文章主要介紹了Python線程threading模塊用法,結(jié)合實(shí)例形式總結(jié)分析了Python線程threading模塊基本功能、原理、相關(guān)函數(shù)使用方法與操作注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了Python線程threading模塊用法。分享給大家供大家參考,具體如下:

threading-更高級別的線程接口

源代碼:Lib/threading.py
該模塊在較低級別thread模塊之上構(gòu)建更高級別的線程接口。另請參見mutex和Queue模塊。

該dummy_threading模塊適用于threading因thread缺失而無法使用的情況 。

注意: 從Python 2.6開始,該模塊提供 符合 PEP 8的別名和屬性,以替換camelCase受Java的線程API啟發(fā)的名稱。此更新的API與multiprocessing模塊的API兼容 。但是,沒有為camelCase名稱的棄用設(shè)置計(jì)劃,它們在Python 2.x和3.x中仍然完全受支持。


注意 :從Python 2.5開始,幾個(gè)Thread方法引發(fā)RuntimeError 而不是AssertionError錯(cuò)誤地調(diào)用。

該模塊定義了以下功能和對象:

threading.active_count()
threading.activeCount()
返回Thread當(dāng)前活動(dòng)的對象數(shù)。返回的計(jì)數(shù)等于返回的列表的長度enumerate()。

在2.6版中更改:添加了active_count()拼寫。

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

請參閱條件對象。

threading.current_thread()
threading.currentThread()
返回當(dāng)前Thread對象,對應(yīng)于調(diào)用者的控制線程。如果未通過threading模塊創(chuàng)建調(diào)用者的控制 線程,則返回具有有限功能的虛擬線程對象。

在2.6版中更改:添加了current_thread()拼寫。

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

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

請參閱事件對象。

類threading.local
表示線程局部數(shù)據(jù)的類。線程局部數(shù)據(jù)是其值是線程特定的數(shù)據(jù)。要管理線程本地?cái)?shù)據(jù),只需創(chuàng)建一個(gè)local(或子類)實(shí)例并在其上存儲(chǔ)屬性:

mydata = threading.local()
mydata.x = 1

對于單獨(dú)的線程,實(shí)例的值將不同。

有關(guān)更多詳細(xì)信息和大量示例,請參閱_threading_local模塊的文檔字符串 。

版本2.4中的新功能。

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

請參見鎖定對象。

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

請參閱RLock對象。

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

請參見信號量對象。

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

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

請參見線程對象。

類 threading.Timer
在指定的時(shí)間間隔過后執(zhí)行函數(shù)的線程。

見Timer對象。

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

版本2.3中的新功能。

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

版本2.3中的新功能。

threading.stack_size([ 大小] )
返回創(chuàng)建新線程時(shí)使用的線程堆棧大小??蛇x的 size參數(shù)指定用于后續(xù)創(chuàng)建的線程的堆棧大小,并且必須為0(使用平臺或已配置的默認(rèn)值)或至少為32,768(32 KiB)的正整數(shù)值。如果未指定size,則使用0。如果不支持更改線程堆棧大小,ThreadError則引發(fā)a。如果指定的堆棧大小無效,則aValueError被提升,堆棧大小未經(jīng)修改。32kB是目前支持的最小堆棧大小值,以保證解釋器本身有足夠的堆棧空間。請注意,某些平臺可能對堆棧大小的值有特定限制,例如要求最小堆棧大小> 32kB或需要以系統(tǒng)內(nèi)存頁面大小的倍數(shù)進(jìn)行分配 - 應(yīng)提供平臺文檔以獲取更多信息(4kB頁面是常見的;在沒有更具體的信息的情況下,建議的方法是使用4096的倍數(shù)作為堆棧大小??捎眯裕篧indows,具有POSIX線程的系統(tǒng)。

2.5版中的新功能。

異常threading.ThreadError
針對各種與線程相關(guān)的錯(cuò)誤提出,如下所述。請注意,許多接口使用RuntimeError而不是ThreadError。

下面記錄了對象的詳細(xì)界面。

該模塊的設(shè)計(jì)基于Java的線程模型。但是,在Java使鎖和條件變量成為每個(gè)對象的基本行為的地方,它們是Python中的獨(dú)立對象。Python的Thread類支持Java的Thread類的行為的子集; 目前,沒有優(yōu)先級,沒有線程組,線程不能被銷毀,停止,暫停,恢復(fù)或中斷。Java的Thread類的靜態(tài)方法在實(shí)現(xiàn)時(shí)會(huì)映射到模塊級函數(shù)。

下面描述的所有方法都是原子執(zhí)行的。

線程對象

此類表示在單獨(dú)的控制線程中運(yùn)行的活動(dòng)。有兩種方法可以指定活動(dòng):將可調(diào)用對象傳遞給構(gòu)造函數(shù),或者通過覆蓋run()子類中的方法。不應(yīng)在子類中重寫其他方法(構(gòu)造函數(shù)除外)。換句話說, 只 覆蓋此類的init()和run()方法。

創(chuàng)建線程對象后,必須通過調(diào)用線程的start()方法啟動(dòng)其活動(dòng)。這將run()在單獨(dú)的控制線程中調(diào)用該方法。

一旦線程的活動(dòng)開始,線程就被認(rèn)為是“活著的”。當(dāng)它的run()方法終止時(shí),它會(huì)停止活動(dòng)- 通常,或者通過引發(fā)未處理的異常。該is_alive()方法測試線程是否存活。

其他線程可以調(diào)用線程的join()方法。這會(huì)阻塞調(diào)用線程,直到調(diào)用其join()方法的線程終止。

線程有一個(gè)名字。名稱可以傳遞給構(gòu)造函數(shù),并通過name屬性讀取或更改。

線程可以標(biāo)記為“守護(hù)程序線程”。這個(gè)標(biāo)志的意義在于當(dāng)只剩下守護(hù)進(jìn)程線程時(shí)整個(gè)Python程序退出。初始值繼承自創(chuàng)建線程??梢酝ㄟ^daemon酒店設(shè)置標(biāo)志。

注意:守護(hù)程序線程在關(guān)閉時(shí)突然停止。他們的資源(例如打開文件,數(shù)據(jù)庫事務(wù)等)可能無法正確發(fā)布。如果您希望線程正常停止,請使它們成為非守護(hù)進(jìn)程并使用合適的信令機(jī)制,例如Event。

有一個(gè)“主線程”對象; 這對應(yīng)于Python程序中的初始控制線程。它不是守護(hù)程序線程。

有可能創(chuàng)建“虛擬線程對象”。這些是與“外部線程”相對應(yīng)的線程對象,它們是在線程模塊外部啟動(dòng)的控制線程,例如直接來自C代碼。虛擬線程對象具有有限的功能; 他們總是被認(rèn)為是活著的和守護(hù)的,不能被join()編輯。它們永遠(yuǎn)不會(huì)被刪除,因?yàn)闊o法檢測外來線程的終止。

class threading.Thread(group = None,target = None,name = None,args =(),kwargs = {} )
應(yīng)始終使用關(guān)鍵字參數(shù)調(diào)用此構(gòu)造函數(shù)。參數(shù)是:

小組應(yīng)該None; 在實(shí)現(xiàn)ThreadGroup類時(shí)為將來的擴(kuò)展保留 。

target是run()方法調(diào)用的可調(diào)用對象。默認(rèn)為None,意味著什么都沒有被調(diào)用。

name是線程名稱。默認(rèn)情況下,唯一名稱由“Thread- N ” 形式構(gòu)成,其中N是小十進(jìn)制數(shù)。

args是目標(biāo)調(diào)用的參數(shù)元組。默認(rèn)為()。

kwargs是目標(biāo)調(diào)用的關(guān)鍵字參數(shù)字典。默認(rèn)為{}。

如果子類重寫構(gòu)造函數(shù),則必須確保Thread.init()在對線程執(zhí)行任何其他操作之前調(diào)用基類構(gòu)造函數(shù)()。
start()
開始線程的活動(dòng)。

每個(gè)線程對象最多只能調(diào)用一次。它安排run()在單獨(dú)的控制線程中調(diào)用對象的方法。

此方法將RuntimeError在同一個(gè)線程對象上多次調(diào)用if。

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

您可以在子類中重寫此方法。標(biāo)準(zhǔn)run() 方法調(diào)用傳遞給對象構(gòu)造函數(shù)的可調(diào)用對象作為目標(biāo)參數(shù)(如果有),分別使用args和kwargs參數(shù)中的順序和關(guān)鍵字參數(shù)。

join([ 超時(shí)] )
等到線程終止。這將阻塞調(diào)用線程,直到調(diào)用其join()方法的線程終止 - 正?;蛲ㄟ^未處理的異常 - 或直到發(fā)生可選的超時(shí)。

當(dāng)超時(shí)參數(shù)存在而不存在時(shí)None,它應(yīng)該是一個(gè)浮點(diǎn)數(shù),指定操作的超時(shí)(以秒為單位)(或其中的分?jǐn)?shù))。由于join()總是返回None,必須調(diào)用isAlive()后join()決定超時(shí)是否發(fā)生了-如果線程還活著時(shí),join()調(diào)用超時(shí)。

當(dāng)timeout參數(shù)不存在時(shí)None,操作將阻塞,直到線程終止。

線程可以join()多次編輯。

join()提出了RuntimeError如果試圖加入當(dāng)前線程因?yàn)檫@將導(dǎo)致死鎖。join()在線程啟動(dòng)之前它也是一個(gè)錯(cuò)誤, 并且嘗試這樣做會(huì)引發(fā)相同的異常。

name
字符串僅用于識別目的。它沒有語義。多個(gè)線程可以賦予相同的名稱。初始名稱由構(gòu)造函數(shù)設(shè)置。

版本2.6中的新功能。

getName()
setName()
適用于2.6之前的API name。

ident
此線程的“線程標(biāo)識符”或者None線程尚未啟動(dòng)。這是一個(gè)非零整數(shù)???thread.get_ident()功能。當(dāng)線程退出并創(chuàng)建另一個(gè)線程時(shí),可以回收線程標(biāo)識符。即使在線程退出后,該標(biāo)識符也可用。

版本2.6中的新功能。

is_alive()
isAlive()
返回線程是否存活。

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

在2.6版中更改:添加了is_alive()拼寫。

daemon
一個(gè)布爾值,指示此線程是否為守護(hù)程序線程(True)或不是(False)。必須在start()調(diào)用之前設(shè)置,否則RuntimeError引發(fā)。它的初始值繼承自創(chuàng)建線程; 主線程不是守護(hù)程序線程,因此在主線程中創(chuàng)建的所有線程都默認(rèn)為daemon = False。

當(dāng)沒有剩下活著的非守護(hù)進(jìn)程線程時(shí),整個(gè)Python程序退出。

版本2.6中的新功能。

isDaemon(
setDaemon()
適用于2.6之前的API daemon。

鎖定對象

原始鎖是一種同步原語,在鎖定時(shí)不屬于特定線程。在Python中,它是目前可用的最低級同步原語,由thread 擴(kuò)展模塊直接實(shí)現(xiàn)。

原始鎖定處于“鎖定”或“解鎖”兩種狀態(tài)之一。它是在解鎖狀態(tài)下創(chuàng)建的。它有兩種基本方法,acquire()和 release()。當(dāng)狀態(tài)解鎖時(shí),acquire()將狀態(tài)更改為鎖定并立即返回。當(dāng)狀態(tài)被鎖定時(shí),acquire() 阻塞直到release()另一個(gè)線程中的調(diào)用將其更改為解鎖,然后該acquire()調(diào)用將其重置為已鎖定并返回。該 release()方法只應(yīng)在鎖定狀態(tài)下調(diào)用; 它將狀態(tài)更改為已解鎖并立即返回。如果嘗試釋放未鎖定的鎖,ThreadError則會(huì)引發(fā)a。

當(dāng)acquire()等待狀態(tài)轉(zhuǎn)為解鎖時(shí)阻塞多個(gè)線程時(shí),只有一個(gè)線程在release()呼叫重置狀態(tài)解鎖時(shí)繼續(xù); 哪個(gè)等待線程繼續(xù)進(jìn)行未定義,并且可能因?qū)崿F(xiàn)而異。

所有方法都以原子方式執(zhí)行。

Lock.acquire([ 阻止] )
獲取鎖定,阻止或非阻止。

當(dāng)阻塞參數(shù)設(shè)置為True(默認(rèn)值)時(shí)調(diào)用,阻塞直到解鎖,然后將其設(shè)置為鎖定并返回True。

在使用阻塞參數(shù)設(shè)置為的情況下調(diào)用時(shí)False,請勿阻止。如果一個(gè)帶阻塞的調(diào)用設(shè)置為True阻塞,則False 立即返回; 否則,將鎖定設(shè)置為鎖定并返回True。

Lock.release()
解鎖。

鎖定鎖定后,將其重置為解鎖狀態(tài),然后返回。如果阻止任何其他線程等待鎖解鎖,則只允許其中一個(gè)繼續(xù)執(zhí)行。

在未鎖定的鎖上調(diào)用時(shí),ThreadError會(huì)引發(fā)a。

沒有回報(bào)價(jià)值。

RLock對象

可重入鎖是同步原語,可以由同一線程多次獲取。在內(nèi)部,除了原始鎖使用的鎖定/解鎖狀態(tài)之外,它還使用“擁有線程”和“遞歸級別”的概念。在鎖定狀態(tài)下,某些線程擁有鎖; 在解鎖狀態(tài)下,沒有線程擁有它。

要鎖定鎖,線程會(huì)調(diào)用其acquire()方法; 一旦線程擁有鎖,它就會(huì)返回。要解鎖鎖,線程會(huì)調(diào)用其 release()方法。acquire()/ release()call對可以嵌套; 只有最后一個(gè)release()(release()最外面的一對)重置鎖才能解鎖并允許另一個(gè)被阻塞的線程 acquire()繼續(xù)進(jìn)行。

RLock.acquire([ blocking = 1 ] )
獲取鎖定,阻止或非阻止。

在不帶參數(shù)的情況下調(diào)用:如果此線程已擁有鎖,則將遞歸級別遞增1,并立即返回。否則,如果另一個(gè)線程擁有該鎖,則阻塞直到鎖被解鎖。鎖解鎖后(不屬于任何線程),然后獲取所有權(quán),將遞歸級別設(shè)置為1,然后返回。如果多個(gè)線程被阻塞等待鎖解鎖,則一次只能有一個(gè)線程獲取鎖的所有權(quán)。在這種情況下沒有返回值。

在將blocking參數(shù)設(shè)置為true的情況下調(diào)用時(shí),執(zhí)行與不帶參數(shù)調(diào)用時(shí)相同的操作,并返回true。

在將blocking參數(shù)設(shè)置為false的情況下調(diào)用時(shí),請勿阻止。如果沒有參數(shù)的調(diào)用會(huì)阻塞,則立即返回false; 否則,執(zhí)行與不帶參數(shù)調(diào)用時(shí)相同的操作,并返回true。

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

僅在調(diào)用線程擁有鎖時(shí)調(diào)用此方法。RuntimeError如果在鎖定解鎖時(shí)調(diào)用此方法,則引發(fā)A.

沒有回報(bào)價(jià)值。

條件對象

條件變量總是與某種鎖相關(guān)聯(lián); 這可以傳入,或者默認(rèn)創(chuàng)建一個(gè)。(當(dāng)多個(gè)條件變量必須共享同一個(gè)鎖時(shí),傳入一個(gè)是有用的。)

條件變量具有acquire()與release()該調(diào)用相關(guān)聯(lián)的鎖的相應(yīng)方法的方法。它還有一種wait() 方法notify()和notifyAll()方法。只有在調(diào)用線程獲得鎖定時(shí)才調(diào)用這三個(gè),否則 RuntimeError引發(fā)a。

該wait()方法釋放鎖,然后阻塞,直到它被另一個(gè)線程中的相同條件變量喚醒notify()或notifyAll()調(diào)用。一旦被喚醒,它就會(huì)重新獲得鎖并返回。也可以指定超時(shí)。

該notify()方法喚醒等待條件變量的其中一個(gè)線程,如果有的話正在等待。該notifyAll()方法喚醒等待條件變量的所有線程。

注意:notify()和notifyAll()方法不釋放鎖; 這意味著被喚醒的一個(gè)或多個(gè)線程不會(huì)wait()立即從它們的調(diào)用返回,而是僅在調(diào)用notify()或notifyAll()最終放棄鎖的所有權(quán)的線程時(shí) 返回 。

提示:使用條件變量的典型編程風(fēng)格使用鎖來同步對某些共享狀態(tài)的訪問; 對狀態(tài)的特定變化感興趣的線程wait()重復(fù)調(diào)用,直到它們看到所需的狀態(tài),而線程修改狀態(tài)調(diào)用notify()或者 notifyAll()當(dāng)它們改變狀態(tài)時(shí)它可能是其中一個(gè)服務(wù)員的期望狀態(tài)。例如,以下代碼是具有無限緩沖區(qū)容量的通用生產(chǎn)者 - 消費(fèi)者情況:

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

要在notify()和之間進(jìn)行選擇notifyAll(),請考慮一個(gè)狀態(tài)更改是否只對一個(gè)或多個(gè)等待線程感興趣。例如,在典型的生產(chǎn)者 - 消費(fèi)者情況下,向緩沖區(qū)添加一個(gè)項(xiàng)目只需要喚醒一個(gè)消費(fèi)者線程。

class threading.Condition([ lock ] )
如果給出了lock參數(shù)None,則它必須是一個(gè)Lock 或RLock對象,并且它被用作底層鎖。否則,將RLock創(chuàng)建一個(gè)新對象并將其用作基礎(chǔ)鎖。

acquire(* args )
獲取底層鎖。此方法在底層鎖上調(diào)用相應(yīng)的方法; 返回值是該方法返回的任何值。

release()
釋放底層鎖。此方法在底層鎖上調(diào)用相應(yīng)的方法; 沒有回報(bào)價(jià)值。

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

此方法釋放底層鎖,然后阻塞,直到它被另一個(gè)線程中的相同條件變量喚醒notify()或notifyAll()調(diào)用,或者直到發(fā)生可選超時(shí)。一旦被喚醒或超時(shí),它就會(huì)重新獲得鎖定并返回。

當(dāng)超時(shí)參數(shù)存在而不存在時(shí)None,它應(yīng)該是一個(gè)浮點(diǎn)數(shù),指定操作的超時(shí)(以秒為單位)(或其中的分?jǐn)?shù))。

當(dāng)?shù)讓渔i是a時(shí)RLock,它不會(huì)使用其release()方法釋放,因?yàn)楫?dāng)遞歸多次獲取鎖時(shí),這實(shí)際上可能無法解鎖。相反,使用了RLock類的內(nèi)部接口,即使多次遞歸獲取它也能真正解鎖它。然后,在重新獲取鎖時(shí),使用另一個(gè)內(nèi)部接口來恢復(fù)遞歸級別。

notify(n = 1 )
默認(rèn)情況下,喚醒一個(gè)等待此條件的線程(如果有)。如果在調(diào)用此方法時(shí)調(diào)用線程尚未獲取鎖定, RuntimeError則引發(fā)a。

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

如果至少有n個(gè) 線程在等待,那么當(dāng)前的實(shí)現(xiàn)只會(huì)喚醒n 個(gè)線程。但是,依靠這種行為是不安全的。未來的優(yōu)化實(shí)現(xiàn)有時(shí)可能會(huì)喚醒超過 n個(gè)線程。

注意:喚醒線程實(shí)際上不會(huì)從其wait() 調(diào)用返回,直到它可以重新獲取鎖定。由于notify()不釋放鎖,其調(diào)用者應(yīng)該。

notify_all()
notifyAll()
喚醒等待這種情況的所有線程。這種方法就像 notify(),但喚醒所有等待的線程而不是一個(gè)。如果在調(diào)用此方法時(shí)調(diào)用線程尚未獲取鎖定, RuntimeError則引發(fā)a。

在2.6版中更改:添加了notify_all()拼寫。

信號量對象

這是計(jì)算機(jī)科學(xué)史上最古老的同步原語之一,由早期的荷蘭計(jì)算機(jī)科學(xué)家Edsger W. Dijkstra(他使用P()而V()不是acquire()和release())發(fā)明。

信號量管理一個(gè)內(nèi)部計(jì)數(shù)器,該計(jì)數(shù)器按每次acquire()調(diào)用遞減并按每次 調(diào)用遞增release()。計(jì)數(shù)器永遠(yuǎn)不會(huì)低于零; 當(dāng)acquire()發(fā)現(xiàn)它為零時(shí),它會(huì)阻塞,等待其他線程調(diào)用release()。

class threading.Semaphore([ value ] )
可選參數(shù)給出內(nèi)部計(jì)數(shù)器的初始值 ; 它默認(rèn)為1。如果給定的值小于0,ValueError則引發(fā)。

acquire([ 阻止] )
獲取信號量。

在不帶參數(shù)的情況下調(diào)用:如果內(nèi)部計(jì)數(shù)器在輸入時(shí)大于零,則將其減1并立即返回。如果在進(jìn)入時(shí)為零,則阻塞,等待其他線程調(diào)用 release()以使其大于零。這是通過適當(dāng)?shù)幕ユi來完成的,這樣如果多個(gè)acquire()呼叫被阻止,它們 release()將完全喚醒其中一個(gè)。實(shí)現(xiàn)可以隨機(jī)選擇一個(gè),因此不應(yīng)該依賴被阻塞的線程被喚醒的順序。在這種情況下沒有返回值。

當(dāng)使用blocking設(shè)置為true 調(diào)用時(shí),執(zhí)行與不帶參數(shù)調(diào)用時(shí)相同的操作,并返回true。

當(dāng)阻塞設(shè)置為false 時(shí)調(diào)用,請勿阻止。如果沒有參數(shù)的調(diào)用會(huì)阻塞,則立即返回false; 否則,執(zhí)行與不帶參數(shù)調(diào)用時(shí)相同的操作,并返回true。

release()
釋放信號量,將內(nèi)部計(jì)數(shù)器遞增1。當(dāng)它在進(jìn)入時(shí)為零并且另一個(gè)線程正在等待它再次大于零時(shí),喚醒該線程。

Semaphore示例

信號量通常用于保護(hù)容量有限的資源,例如數(shù)據(jù)庫服務(wù)器。在資源大小固定的任何情況下,您應(yīng)該使用有界信號量。在產(chǎn)生任何工作線程之前,您的主線程將初始化信號量:

maxconnections = 5
...
pool_sema = BoundedSemaphore(value=maxconnections)

一旦產(chǎn)生,工作線程在需要連接到服務(wù)器時(shí)調(diào)用信號量的獲取和釋放方法:

pool_sema.acquire()
conn = connectdb()
... use connection ...
conn.close()
pool_sema.release()

有界信號量的使用減少了導(dǎo)致信號量被釋放的編程錯(cuò)誤超過其獲取的編程錯(cuò)誤的可能性。

事件對象

這是線程之間通信的最簡單機(jī)制之一:一個(gè)線程發(fā)出事件信號,其他線程等待它。

事件對象管理一個(gè)內(nèi)部標(biāo)志,該標(biāo)志可以使用該set()方法設(shè)置為true,并使用該 方法重置為false clear() 。該wait()方法將阻塞,直到該標(biāo)志為真。

類threading.Event
內(nèi)部標(biāo)志最初是假的。

is_set()
isSet()
當(dāng)且僅當(dāng)內(nèi)部標(biāo)志為真時(shí)返回true。

在2.6版中更改:添加了is_set()拼寫。

set()
將內(nèi)部標(biāo)志設(shè)置為true。等待它變?yōu)檎娴乃芯€程都被喚醒。wait()一旦標(biāo)志為真,調(diào)用的線程將不會(huì)阻塞。

clear()
將內(nèi)部標(biāo)志重置為false。隨后,線程調(diào)用 wait()將阻塞,直到set()被調(diào)用以再次將內(nèi)部標(biāo)志設(shè)置為true。

wait([ 超時(shí)] )
阻止,直到內(nèi)部標(biāo)志為真。如果輸入時(shí)內(nèi)部標(biāo)志為真,則立即返回。否則,阻塞直到另一個(gè)線程調(diào)用 set()將標(biāo)志設(shè)置為true,或者直到發(fā)生可選的超時(shí)。

當(dāng)超時(shí)參數(shù)存在而不存在時(shí)None,它應(yīng)該是一個(gè)浮點(diǎn)數(shù),指定操作的超時(shí)(以秒為單位)(或其中的分?jǐn)?shù))。

此方法在退出時(shí)返回內(nèi)部標(biāo)志,因此它將始終返回, True除非給出超時(shí)并且操作超時(shí)。

在2.7版中更改:以前,該方法始終返回None。

定時(shí)器對象

此類表示應(yīng)該在經(jīng)過一定時(shí)間后運(yùn)行的操作 - 計(jì)時(shí)器。 Timer是一個(gè)子類,Thread 因此也可以作為創(chuàng)建自定義線程的示例。

通過調(diào)用start() 方法,啟動(dòng)計(jì)時(shí)器,就像使用線程一樣。通過調(diào)用cancel()方法可以停止計(jì)時(shí)器(在其動(dòng)作開始之前) 。計(jì)時(shí)器在執(zhí)行其操作之前將等待的時(shí)間間隔可能與用戶指定的時(shí)間間隔不完全相同。

例如:

def hello():
  print "hello, world"

t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed

class threading.Timer(interval,function,args = [],kwargs = {} )
創(chuàng)建一個(gè)計(jì)時(shí)器,在經(jīng)過間隔秒后,將使用參數(shù)args和關(guān)鍵字參數(shù)kwargs運(yùn)行函數(shù)。

cancel()
停止計(jì)時(shí)器,取消執(zhí)行計(jì)時(shí)器的操作。這只有在計(jì)時(shí)器仍處于等待階段時(shí)才有效。

在with語句中使用鎖,條件和信號量

此模塊提供的具有acquire()和 release()方法的所有對象都可以用作with 語句的上下文管理器。acquire()進(jìn)入塊時(shí)將調(diào)用該方法,并release()在退出塊時(shí)調(diào)用該方法。

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

import threading

some_rlock = threading.RLock()

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

在線程代碼中導(dǎo)入

雖然導(dǎo)入機(jī)制是線程安全的,但由于提供線程安全的方式存在固有限制,因此線程導(dǎo)入有兩個(gè)主要限制:

  • 首先,除了在主模塊中,導(dǎo)入不應(yīng)該產(chǎn)生產(chǎn)生新線程然后以任何方式等待該線程的副作用。如果生成的線程直接或間接嘗試導(dǎo)入模塊,則不遵守此限制可能導(dǎo)致死鎖。
  • 其次,所有導(dǎo)入嘗試必須在解釋器開始關(guān)閉之前完成。僅通過從通過線程模塊創(chuàng)建的非守護(hù)程序線程執(zhí)行導(dǎo)入,可以最容易地實(shí)現(xiàn)這一點(diǎn)。直接使用線程模塊創(chuàng)建的守護(hù)程序線程和線程將需要一些其他形式的同步,以確保在系統(tǒng)關(guān)閉開始后它們不會(huì)嘗試導(dǎo)入。不遵守此限制將導(dǎo)致在解釋器關(guān)閉期間出現(xiàn)間歇性異常和崩潰(因?yàn)楹笃趯?dǎo)入嘗試訪問不再處于有效狀態(tài)的機(jī)器)。

更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python進(jìn)程與線程操作技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進(jìn)階經(jīng)典教程》、《Python+MySQL數(shù)據(jù)庫程序設(shè)計(jì)入門教程》及《Python常見數(shù)據(jù)庫操作技巧匯總

希望本文所述對大家Python程序設(shè)計(jì)有所幫助。

相關(guān)文章

最新評論