Python執行緒專題7:條件變數

Mark發表於2019-02-16

上一篇文章:Python執行緒專題6:事件
下一篇文章:Python執行緒專題8:使用鎖的注意事項

條件變數時構建在另一個鎖上的同步原語,當需要執行緒關注特定的狀態變化或事件發生時將使用這個鎖。典型的用法是生產者與消費者問題,其中一個執行緒生產的資料提供給另外一個執行緒使用。

語法:

c=Condition(lock)
穿件新的條件變數。lock時可選的Lock或RLock的例項。如果未提供lock引數,就會建立新的RLock例項供條件變數使用。

常用方法:

c.acquire(*args):獲取底層鎖。此方法將呼叫底層鎖上對應的acquire(*args)方法。

c.release():釋放底層鎖。此方法將呼叫底層鎖上對應的release()方法

c.wait(timeout):等待直到獲取通知或出現超時為止。此方法在呼叫執行緒已經獲取鎖之後呼叫。
呼叫時,將釋放底層鎖,而且執行緒將進入睡眠狀態,直到另一個執行緒在條件變數上執行notify()或notify_all()方法將其喚醒為止。
線上程被喚醒後,執行緒講重新獲取鎖,方法也會返回。timeout是浮點數,單位為秒。
如果超時,執行緒將被喚醒,重新獲取鎖,而控制將被返回。

c.notify(n):喚醒一個或多個等待此條件變數的執行緒。此方法只會在呼叫執行緒已經獲取鎖之後呼叫,
而且如果沒有正在等待的執行緒,它就什麼也不做。
n指定要喚醒的執行緒數量,預設為1.被喚醒的執行緒在它們重新獲取鎖之前不會從wait()呼叫返回。

c.notify_all():喚醒所有等待此條件的執行緒。

例項模版:使用條件變數

#條件變數例項
from threading import Condition

c=Condition()
def producer():
    while True:
        c.acquire()
        #生產東西
        ...
        c.notify()
        c.release()

def consumer():
    while True:
        c.acquire()
        while 沒有可用的東西:
            c.wait()#等待出現
        c.release()
        #使用生產的東西
        ...

注意:如果存在多個執行緒等待同一個條件,notify()操作會喚醒他們中的一個或多個(這種行為取決於底層的作業系統)。因此,始終有這樣的可能:某個執行緒被喚醒後,缺發現它等待的條件不存在了,這解釋了為什麼在consumer函式中使用while迴圈,如果執行緒醒來,但是生成的項已經消失,它就會回去等待下一個訊號。

相關文章