1. 程式人生 > >Python中多執行緒總結

Python中多執行緒總結

Python中的多執行緒


多執行緒


一個程序中有多個執行緒就是多執行緒。

一個程序中至少有一個執行緒,並作為程式的入口,這個就是主執行緒。一個程序至少有一個主程序,其他執行緒稱為工作執行緒。


執行緒安全:執行緒執行一段程式碼,不會產生不確定的結果,那這段程式碼就是執行緒安全。(例如print()執行緒不安全)



執行緒的daemon屬性


daemon屬性:表示執行緒是否是daemon執行緒,這個值必須在start()之前設定,否則引發RuntimeError異常

isDaemon():是否是daemon執行緒

setDaemon():設定為daemon執行緒,必須在start方法之前設定


執行緒具有一個daemon屬性,可以設定為Ture或False,也可以不設定,預設值為None.如果不設定daemon就取當前的daemon來設定它,主執行緒是Non-daemon。工作執行緒不設定daemon屬性,則預設是daemon = False .python程式在沒有活著的non-daemon執行緒執行時退出。



join()方法

join(timeout)是執行緒的標準方法之一。

一個執行緒中呼叫裡那個一個執行緒的join方法,呼叫者將被阻塞,知道盜用執行緒終止。一個執行緒可以被join多次。



daemon執行緒的應用場景

1:後臺任務,如傳送心跳包、監控,這種場景最多

2:主執行緒工作才有用的執行緒,如主執行緒中維護的公共資源,主執行緒已經清理了,準備退出,而工作執行緒使用這些資源工作也沒有意義了,一起退出最合適。

3:隨時可以被終止的執行緒


threading.local類

執行時,threading.local例項處在不同的執行緒中,就從大字典中找到當前執行緒相關鍵值對中的字典,覆蓋threading.local例項的__dict__。這樣就可以在不同的執行緒中,安全德使用執行緒獨有的資料做到執行緒間資料隔離,如同本地變數一樣安全。


定時器Timer/延遲執行


threading.Timer(interval,function,args=None,Kwargs=None)

start方法執行之後,Timer物件會處於等待狀態,等待了interval秒之後,開始執行function函式的。Timer提供了cancel方法,用來取消一個未執行的函式。


Event

是執行緒間通訊機制中最簡單的實現,使用一個內部的標記flag,通過flag的True或False的表換來進行操作。

set():標記設定為Ture

clear():標記設定為False

is_set():標記是否為Ture

wait(timeou):設定等待標記為Ture的時長,None為無限等待,等到返回Ture,未等到超時了返回False


Event的wait優於time.sleep,他會更快的切換到其它執行緒,提高併發效率。


lock


鎖,凡是存在共享資源爭搶的地方都可以使用鎖,從而保證只有一個使用者可以完全使用這個資源。一旦執行緒獲得鎖,其他試圖獲取鎖的執行緒將被阻塞。

acquire(blocking=True,timeout=-1):預設阻塞,阻塞可以設定超時時間,非阻塞時,timeout禁止設定。成功獲取鎖,返回True,否則返回Flase

release():釋放鎖,可以從任何執行緒呼叫釋放。已上鎖的多,會被重置未unlocked。未上鎖的呼叫,會派出RuntimeError異常。


加鎖、解鎖

一般來說,加鎖就需要解鎖,但加鎖後解鎖前,還有一些程式碼執行,就有可能丟擲異常,一旦出現異常,鎖無法釋放,但是當前執行緒可能因為這個異常被終止了,這就產生了死鎖。

加鎖、解鎖常用的語句:

1:使用try ... funally語句保證鎖的釋放

2:with上下文管理,鎖隨想支援上下位管理。


鎖的應用:

鎖適合用於訪問和修改同一個共享資源的時候,即讀寫同一個資源的時候。

注意事項:

1:少用鎖,必要時使用鎖,使用了鎖,多執行緒訪問被鎖的資源時,就成了序列,要麼排隊執行,要麼爭搶執行。

2:加鎖時間越短越好,不需要就立即釋放。

3:一定要避免死鎖。


Rlock可重入鎖

可重入鎖,是執行緒相關的鎖。可在一個執行緒中獲取鎖,並可繼續在同一個執行緒中不阻塞獲取鎖,當鎖為釋放完,其他執行緒獲取鎖就會阻塞。知道當前持有鎖的執行緒釋放完鎖。



Conditon

構造方法Consition(lock=None),可以傳入一個Lock或者Rlock物件,預設是Rlock


acquire(*args):獲取鎖

wait(self.timeout=None):等待或超時

notify(n =1):喚醒至多指定數目個數的等待的執行緒,沒有執行緒等待的執行緒就沒有任何操作

notify_all():喚醒所有等待的執行緒

condition用於生產者,消費者模型,為了解決生產者消費者速度匹配的問題。由於condition內部使用了鎖,最好的方式是使用with上下文。


Barrier

Barrier(parties,action=None,timeout=None):構建Barrier物件,指定參與方數目。timeout是wait方法未指定超時的預設值。

n_waiting:當前在barrier中等待的執行緒數

parties:資源的個數。

broken:如果broken處於打破的狀態,放回True

abort():將將barrier置於broken狀態,等待中的執行緒或者呼叫等待方法的執行緒中都會丟擲BrokenBarrierError異常,知道reset方法來恢復barrier

reset():恢復barrier,重新開始攔截。


wait方法超時發生,barrier將處於broken狀態,知道reset()


semaphore訊號量

Semaphore(value=1):構造方法,value小於0,拋ValueError異常

acquite(blocking=True,timeout=None):獲取訊號量,計數器減1,獲取成功返回True

release():釋放訊號量,計數器加1


semaphore問題

如果遇到release釋放次數大於初始值,計數器會增加,超過我們的最大值。

解決方法:

使用Boundedsemaphore類,有界訊號量,不允許使用release超出初始值的範圍,否則派出ValueError異常。


鎖和訊號量

鎖,只允許同一個時間一個執行緒獨佔資源,它是特殊的訊號量,即訊號量計數器初始值為1.

訊號量,可以多個執行緒訪問共享資源,但這個共享資源數量有限。

鎖,可以看做特殊的型號量。