多線程之Condition

多線程之Condition

咱們這說Condition,多線程編程中使用Condition對象代替lock, 可以實如今某個事件觸發後才處理數據。
Condition版的生產者與消費者模式:
Lock版本的生產者與消費者模式能夠正常的運行。可是存在一個不足,在消費者中,老是經過while True死循環而且上鎖的方式去判斷錢夠不夠。上鎖是一個很耗費CPU資源的行爲。
所以這種方式不是最好的。還有一種更好的方式即是使用threading.condition 來實現。threading.Condition 能夠在沒有數據的時候處於阻塞等待狀態。一旦有合適的數據了,還可使用notify相關的函數來通知其餘處於等待狀態的線程。
這樣就能夠不用作一些無用的上鎖和解鎖的操做。能夠提升程序的性能。首先對threading.Condition 相關的函數作個介紹,threading.Condition 類側threading.Lock,能夠在修改全局數據的時候進行上鎖,也能夠在修改完畢後進行解鎖。
如下將一些經常使用的函數作個簡單的介紹:
1.acquire:上鎖。
2.release:解鎖。
3.wait:將當前線程處於等待狀態,而且會釋放鎖。能夠被其餘線程使用notify和notify_all函數喚醒。被喚醒後會繼續等待上鎖,上鎖後繼續執行下面的代碼。
4.notify:通知某個正在等待的線程,默認是第1個等待的線程。
5.notify-o11:通知全部正在等待的線程。notify和notify-o11不會釋放鎖。而且須要在release以前調用。
Condition 版的生產者與消費者模式代碼以下:
import threading import random import time gMoney=1000 gCondition = threading.Condition()              #等同於threading.Lock
gTimes = 0 gTotalTimes = 5
class Producer(threading.Thread): def run(self): global gMoney global gCondition global gTimes while True: money=random.randint(100,1000) gCondition.acquire() #加鎖(全局變量改變前(gMoney))
            if gTimes>=gTotalTimes: gCondition.release() #解鎖
                print("當前生產者總共生產了%s次" %gTimes) break gMoney += money print("%s當前存入%s元錢,剩餘%s元線" %(threading.current_thread(),money,gMoney)) gTimes+=1 gCondition.notify_all() #通知正在等待的線程(wait)
 gCondition.release() time.sleep(0.5) class Cosumer(threading.Thread): def run(self): global gMoney while True: money = random.randint(100,1000) gCondition.acquire() while gMoney < money: if gTimes >= gTotalTimes: gCondition.release() return
                print("%s準備消費%d元錢,剩餘%d元錢,不足" %(threading.current_thread(),money,gMoney)) gCondition.wait() #等待狀態 (獲取鎖) 直到生產者把錢加上 (有錢了再去排隊消費)
            gMoney -= money print("%s消費了%d元錢,剩餘%d元錢" %(threading.current_thread(),money,gMoney)) gCondition.release() time.sleep(0.5) def main(): for x in range(3): t = Cosumer(name="消費者線程%s" %x) t.start() for y in range(5): t1 = Producer(name="生產者線程%s" %y) t1.start() if __name__ == '__main__': main()

 

相關文章
相關標籤/搜索