您好,登錄后才能下訂單哦!
Python中線程同步的作用是什么,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
假如兩個線程對象t1和t2都要對數值num=0進行增1運算,那么t1和t2都各對num修改10次的話,那么num最終的結果應該為20。但是如果當t1取得num的值時(假如此時num為0),系統把t1調度為“sleeping”狀態,而此時t2轉換為“running”狀態,此時t2獲得的num的值也為0,然后他把num+1的值1賦給num。系統又把t2轉化為“sleeping”狀態,t1為“running”狀態,由于t1已經得到num值為0,所以他也把num+1的值賦給了num為1。本來是2次增1運行,結果卻是num只增了1次。類似這樣的情況在多線程同時執行的時候是有可能發生的。所以為了防止這類情況的出現就要使用Python線程同步機制。
最簡單的同步機制就是“鎖”
鎖對象用threading.RLock類創建
mylock = threading.RLock()
如何使用鎖來Python線程同步呢?線程可以使用鎖的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()
條件變量是如何工作的呢?首先一個Python線程同步成功獲得一個條件變量后,調用此條件變量的wait()方法會導致這個線程釋放這個鎖,并進入“blocked”狀態,直到另一個線程調用同一個條件變量的notify()方法來喚醒那個進入“blocked”狀態的線程。如果調用這個條件變量的notifyAll()方法的話就會喚醒所有的在等待的線程。
如果程序或者線程永遠處于“blocked”狀態的話,就會發生死鎖。所以如果使用了鎖、條件變量等同步機制的話,一定要注意仔細檢查,防止死鎖情況的發生。對于可能產生異常的臨界區要使用異常處理機制中的finally子句來保證釋放鎖。等待一個條件變量的線程必須用notify()方法顯式的喚醒,否則就永遠沉默。保證每一個wait()方法調用都有一個相對應的notify()調用,當然也可以調用notifyAll()方法以防萬一。
關于Python中線程同步的作用是什么問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。