互斥鎖是最簡(jiǎn)單的線程同步機(jī)制,Python提供的Condition對(duì)象提供了對(duì)復(fù)雜線程同步問(wèn)題的支持。Condition被稱為條件變量,除了提供與Lock類似的acquire和release方法外,還提供了wait和notify方法。線程首先acquire一個(gè)條件變量,然后判斷一些條件。如果條件不滿足則wait;如果條件滿足,進(jìn)行一些處理改變條件后,通過(guò)notify方法通知其他線程,其他處于wait狀態(tài)的線程接到通知后會(huì)重新判斷條件。不斷的重復(fù)這一過(guò)程,從而解決復(fù)雜的同步問(wèn)題。 可以認(rèn)為Condition對(duì)象維護(hù)了一個(gè)鎖(Lock/RLock)和一個(gè)waiting池。線程通過(guò)acquire獲得Condition對(duì)象,當(dāng)調(diào)用wait方法時(shí),線程會(huì)釋放Condition內(nèi)部的鎖并進(jìn)入blocked狀態(tài),同時(shí)在waiting池中記錄這個(gè)線程。當(dāng)調(diào)用notify方法時(shí),Condition對(duì)象會(huì)從waiting池中挑選一個(gè)線程,通知其調(diào)用acquire方法嘗試取到鎖。 Condition對(duì)象的構(gòu)造函數(shù)可以接受一個(gè)Lock/RLock對(duì)象作為參數(shù),如果沒有指定,則Condition對(duì)象會(huì)在內(nèi)部自行創(chuàng)建一個(gè)RLock。 除了notify方法外,Condition對(duì)象還提供了notifyAll方法,可以通知waiting池中的所有線程嘗試acquire內(nèi)部鎖。由于上述機(jī)制,處于waiting狀態(tài)的線程只能通過(guò)notify方法喚醒,所以notifyAll的作用在于防止有線程永遠(yuǎn)處于沉默狀態(tài)。 演示條件變量同步的經(jīng)典問(wèn)題是生產(chǎn)者與消費(fèi)者問(wèn)題:假設(shè)有一群生產(chǎn)者(Producer)和一群消費(fèi)者(Consumer)通過(guò)一個(gè)市場(chǎng)來(lái)交互產(chǎn)品。生產(chǎn)者的”策略“是如果市場(chǎng)上剩余的產(chǎn)品少于1000個(gè),那么就生產(chǎn)100個(gè)產(chǎn)品放到市場(chǎng)上;而消費(fèi)者的”策略“是如果市場(chǎng)上剩余產(chǎn)品的數(shù)量多余100個(gè),那么就消費(fèi)3個(gè)產(chǎn)品。用Condition解決生產(chǎn)者與消費(fèi)者問(wèn)題的代碼如下: import threading |
|
來(lái)自: 看風(fēng)景D人 > 《Python》