Python多線程同步學習

來源:互聯網
上載者:User

多個執行線程經常要共用資料,如果僅僅讀取共用資料還好,但是如果多個線程要修改共用資料的話就可能出現無法預料的結果。

同步“鎖”機制

鎖對象用threading.RLock類建立

mylock = threading.RLock()

如何使用鎖來同步線程呢?線程可以使用鎖的acquire() (獲得)方法,這樣鎖就進入“locked”狀態。每次只有一個線程可以獲得鎖。如果當另一個線程試圖獲得這個鎖的時候,就會被系統變為“blocked”狀態,直到那個擁有鎖的線程調用鎖的release() (釋放)方法,這樣鎖就會進入“unlocked”狀態。

“blocked”狀態的線程就會收到一個通知,並有權利獲得鎖。如果多個線程處於“blocked”狀態,所有線程都會先解除“blocked”狀態,然後系統選擇一個線程來獲得鎖,其他的線程繼續沉默(“blocked”)。

import threading
mylock = threading.RLock()
class mythread(threading.Thread)
...
def run(self ...):
... #此處 不可以 放置修改共用資料的代碼
mylock.acquire()
... #此處 可以 放置修改共用資料的代碼
mylock.release()
... #此處 不可以 放置修改共用資料的代碼

我們把修改共用資料的代碼稱為“臨界區”,必須將所有“臨界區”都封閉在同一鎖對象的acquire()和release()方法調用之間。


使用條件變數

鎖只能提供最基本的同步層級。有時需要更複雜的線程同步,例如只在發生某些事件時才訪問一個臨界區(例如當某個數值改變時)。這就要使用“條件變數”。 條件變數用threading.Condition類建立

 mycondition = threading.Condition()

條件變數是如何工作的呢?首先一個線程成功獲得一個條件變數後,調用此條件變數的wait()方法會導致這個線程釋放這個鎖,並進入“blocked”狀態,直到另一個線程調用同一個條件變數的notify()方法來喚醒那個進入“blocked”狀態的線程。如果調用這個條件變數的notifyAll()方法的話就會喚醒所有的在等待的線程。

如果程式或者線程永遠處於“blocked”狀態的話,就會發生死結。所以如果使用了鎖、條件變數等同步機制的話,一定要注意仔細檢查,防止死結情況的發生。對於可能產生異常的臨界區要使用異常處理機制中的finally子句來保證釋放鎖。等待一個條件變數的線程必須用notify()方法顯式的喚醒,否則就永遠沉默。保證每一個wait()方法調用都有一個相對應的notify()調用,當然也可以調用notifyAll()方法以防萬一。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.