1. 程式人生 > >Python執行緒,以及多執行緒帶來的資料錯亂和死鎖的解決方法

Python執行緒,以及多執行緒帶來的資料錯亂和死鎖的解決方法

摘至本人有道雲筆記《Python執行緒》

1.python多執行緒的建立

在Python中,同樣可以實現多執行緒,有兩個標準模組thread和threading,不過我們主要使用更高階的threading模組

threading模組提供的類:  

   Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。

threading 模組提供的常用方法: 

  threading.currentThread(): 返回當前的執行緒變數。 

  threading.enumerate(): 返回一個包含正在執行的執行緒的list。正在執行指執行緒啟動後、結束前,不包括啟動前和終止後的執行緒。 

  threading.activeCount(): 返回正在執行的執行緒數量,與len(threading.enumerate())有相同的結果。

threading 模組提供的常量:

   threading.TIMEOUT_MAX 設定threading全域性超時時間

Thread類

Thread是執行緒類,有兩種使用方法,直接傳入要執行的方法或從Thread繼承並覆蓋run()

1)將要執行的方法作為引數傳給Thread的構造方法

構造方法: 

Thread(group=None, target=None, name=None, args=(), kwargs={}) 

  group: 執行緒組,目前還沒有實現,庫引用中提示必須是None; 

  target: 要執行的方法; 

  name: 執行緒名; 

  args/kwargs: 要傳入方法的引數。

例項方法: 

  isAlive(): 返回執行緒是否在執行。正在執行指啟動後、終止前。 

  get/setName(name): 獲取/設定執行緒名。 

  is/setDaemon(bool): 獲取/設定是後臺執行緒(預設前臺執行緒(False))。(在start之前設定)

    如果是後臺執行緒,主執行緒執行過程中,後臺執行緒也在進行,主執行緒執行完畢後,後臺執行緒不論成功與否,主執行緒和後臺執行緒均停止

         如果是前臺執行緒,主執行緒執行過程中,前臺執行緒也在進行,主執行緒執行完畢後,等待前臺執行緒也執行完成後,程式停止

  start(): 啟動執行緒。 

  join([timeout]): 阻塞當前上下文環境的執行緒,直到呼叫此方法的執行緒終止或到達指定的timeout(可選引數)。

例1:驗證了serDeamon(False)(預設)前臺執行緒,主執行緒執行過程中,前臺執行緒也在進行,主執行緒執行完畢後,等待前臺執行緒也執行完成後,主執行緒停止。

使用迴圈建立多執行緒

 

例2:繼承執行緒類,子類建立執行緒

使用此方法建立執行緒,注意兩點:

1)重寫父類的__init__方法,並呼叫父類的__init__方法

2)例項化子類物件就是建立子執行緒,使用子執行緒物件m的start方法啟動的是,子類裡的run方法(執行緒要做的事)。

2.執行緒鎖和ThreadLocal

1)執行緒鎖

由於多個執行緒之間可以共享資料,那隨之而來的問題就是:多個執行緒同時更改一個變數使用一個資源時,就會出現資料錯亂死鎖等現象。

下面是資料錯亂的例子:

理論上如果順序執行,change方法的每次計算結果都是0。由於兩個執行緒都在同時訪問change方法,就會造成資料錯亂。

對於該問題,出現了Lock。 當訪問某個資源之前,用Lock.acquire()鎖住資源,訪問之後,用Lock.release()釋放資源。

獲得鎖的執行緒用完後一定要釋放鎖,否則那些苦苦等待鎖的執行緒將永遠等待下去,成為死執行緒。所以用try...finally來確保鎖一定會被釋放。

多執行緒程式設計,模型複雜,容易發生衝突,必須用鎖加以隔離,同時,又要小心死鎖的發生。