前言
當小伙伴a在往火鍋里面添加魚丸,這個就是生產者行為;另外一個小伙伴b在吃掉魚丸就是消費者行為。當火鍋里面魚丸達到一定數量加滿后b才能吃,這就是一種條件判斷了。
這就是本篇要講的Condition(條件變量)
Condition
Condition(條件變量)通常與一個鎖關聯。需要在多個Contidion中共享一個鎖時,可以傳遞一個Lock/RLock實例給構造方法,否則它將自己生成一個RLock實例。
可以認為,除了Lock帶有的鎖定池外,Condition還包含一個等待池,池中的線程處於狀態圖中的等待阻塞狀態,直到另一個線程調用notify()/notifyAll()通知;得到通知后線程進入鎖定池等待鎖定。
Condition():
- acquire(): 線程鎖
- release(): 釋放鎖
- wait(timeout): 線程掛起,直到收到一個notify通知或者超時(可選的,浮點數,單位是秒s)才會被喚醒繼續運行。wait()必須在已獲得Lock前提下才能調用,否則會觸發RuntimeError。
- notify(n=1): 通知其他線程,那些掛起的線程接到這個通知之后會開始運行,默認是通知一個正等待該condition的線程,最多則喚醒n個等待的線程。notify()必須在已獲得Lock前提下才能調用,否則會觸發RuntimeError。notify()不會主動釋放Lock。
- notifyAll(): 如果wait狀態線程比較多,notifyAll的作用就是通知所有線程
生產者與消費者
實現場景:當a同學王火鍋里面添加魚丸加滿后(最多5個,加滿后通知b去吃掉),通知b同學去吃掉魚丸(吃到0的時候通知a同學繼續添加)
# coding=utf-8
import threading
import time
con = threading.Condition()
num = 0
# 生產者
class Producer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
# 鎖定線程
global num
con.acquire()
while True:
print "開始添加!!!"
num += 1
print "火鍋里面魚丸個數:%s" % str(num)
time.sleep(1)
if num >= 5:
print "火鍋里面里面魚丸數量已經到達5個,無法添加了!"
# 喚醒等待的線程
con.notify() # 喚醒小伙伴開吃啦
# 等待通知
con.wait()
# 釋放鎖
con.release()
# 消費者
class Consumers(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
con.acquire()
global num
while True:
print "開始吃啦!!!"
num -= 1
print "火鍋里面剩余魚丸數量:%s" %str(num)
time.sleep(2)
if num <= 0:
print "鍋底沒貨了,趕緊加魚丸吧!"
con.notify() # 喚醒其它線程
# 等待通知
con.wait()
con.release()
p = Producer()
c = Consumers()
p.start()
c.start()
運行結果:
開始添加!!!
火鍋里面魚丸個數:1
開始添加!!!
火鍋里面魚丸個數:2
開始添加!!!
火鍋里面魚丸個數:3
開始添加!!!
火鍋里面魚丸個數:4
開始添加!!!
火鍋里面魚丸個數:5
火鍋里面里面魚丸數量已經到達5個,無法添加了!
開始吃啦!!!
火鍋里面剩余魚丸數量:4
開始吃啦!!!
火鍋里面剩余魚丸數量:3
開始吃啦!!!
火鍋里面剩余魚丸數量:2
開始吃啦!!!
火鍋里面剩余魚丸數量:1
開始吃啦!!!
火鍋里面剩余魚丸數量:0
鍋底沒貨了,趕緊加魚丸吧!
開始添加!!!
火鍋里面魚丸個數:1
開始添加!!!
火鍋里面魚丸個數:2
開始添加!!!
火鍋里面魚丸個數:3
開始添加!!!
火鍋里面魚丸個數:4
開始添加!!!
火鍋里面魚丸個數:5
python自動化交流 QQ群:779429633