1. 程式人生 > >python Condition類(鎖)

python Condition類(鎖)

del lap lose bdd 超時 實例 比較 sed ase

Condition(條件變量)通常與一個鎖關聯。需要在多個Contidion中共享一個鎖時,可以傳遞一個Lock/RLock實例給構造方法,否則它將自己生成一個RLock實例。

不理解鎖的,請看上一條隨筆。

Condition():

  • acquire(): 線程鎖
  • release(): 釋放鎖
  • wait(timeout): 線程掛起,直到收到一個notify通知或者超時(可選的,浮點數,單位是秒s)才會被喚醒繼續運行。wait()必須在已獲得Lock前提下才能調用,否則會觸發RuntimeError。
  • notify(n=1): 通知其他線程,那些掛起的線程接到這個通知之後會開始運行,默認是通知一個正等待該condition的線程,最多則喚醒n個等待的線程。notify()必須在已獲得Lock前提下才能調用,否則會觸發RuntimeError。notify()不會主動釋放Lock。
  • notifyAll(): 如果wait狀態線程比較多,notifyAll的作用就是通知所有線程
技術分享圖片
import threading
import time

# 商品
product = None
# 條件變量
con = threading.Condition(threading.Lock())


# 生產者方法
def produce():
    global product

    if con.acquire():
        while True:
            print(我執行了,produce)
            if product is None:
                product 
= anything print(produce...,product) print(plock=,con) # 通知消費者,商品已經生產 con.notify() # 等待通知 con.wait() time.sleep(2) # 消費者方法 def consume(): global product if con.acquire(): while
True: print(我執行了,consume) if product is not None: print(consume...,product) print(clock=,con) product = None # 通知生產者,商品已經沒了 con.notify() # 等待通知 con.wait() time.sleep(2) t2 = threading.Thread(target=consume) t2.start() t1 = threading.Thread(target=produce) t1.start()
1、生產者消費者模型 技術分享圖片
import threading
import time

condition = threading.Condition()
products = 0

class Producer(threading.Thread):
    def run(self):
        global products
        while True:
            if condition.acquire():
                if products < 10:
                    products += 1;
                    print "Producer(%s):deliver one, now products:%s" %(self.name, products)
                    condition.notify()#不釋放鎖定,因此需要下面一句
                    condition.release()
                else:
                    print "Producer(%s):already 10, stop deliver, now products:%s" %(self.name, products)
                    condition.wait();#自動釋放鎖定
                time.sleep(2)

class Consumer(threading.Thread):
    def run(self):
        global products
        while True:
            if condition.acquire():
                if products > 1:
                    products -= 1
                    print "Consumer(%s):consume one, now products:%s" %(self.name, products)
                    condition.notify()
                    condition.release()
                else:
                    print "Consumer(%s):only 1, stop consume, products:%s" %(self.name, products)
                    condition.wait();
                time.sleep(2)

if __name__ == "__main__":
    for p in range(0, 2):
        p = Producer()
        p.start()

    for c in range(0, 3):
        c = Consumer()
        c.start()
2、生產者消費者模型 技術分享圖片
import threading
 
alist = None
condition = threading.Condition()
 
def doSet():
    if condition.acquire():
        while alist is None:
            condition.wait()
        for i in range(len(alist))[::-1]:
            alist[i] = 1
        condition.release()
 
def doPrint():
    if condition.acquire():
        while alist is None:
            condition.wait()
        for i in alist:
            print i,
        print
        condition.release()
 
def doCreate():
    global alist
    if condition.acquire():
        if alist is None:
            alist = [0 for i in range(10)]
            condition.notifyAll()
        condition.release()
 
tset = threading.Thread(target=doSet,name=tset)
tprint = threading.Thread(target=doPrint,name=tprint)
tcreate = threading.Thread(target=doCreate,name=tcreate)
tset.start()
tprint.start()
tcreate.start()
3、生產者消費者模型

總結

1、release和wait都有釋放鎖的作用,不同在於wait後,該子線程就在那裏掛起等待,要繼續執行,就需要接收到notify或者notifyAll來喚醒線程,而release該線程還能繼續執行。

2、notify和notifyAll的區別在於,notify只能喚醒一個wait,而notifyAll能喚起所有wait。

python Condition類(鎖)