2014-02-14 92 views
3

在Windows 7上運行的Python 2.6和2.7和Server 2012中Python的事件::等待與超時延遲給出

事件::因爲與事件在時間設置未觸發超時使用時的等待造成的延遲。我不明白爲什麼。

有人可以解釋一下嗎?

下面的程序顯示了這一點並給出了可能的解釋;

'''Shows that using a timeout in Event::wait (same for Queue::wait) causes a 
delay. This is perhaps caused by a polling loop inside the wait implementation. 
This polling loop sleeps some time depending on the timeout. 
Probably wait timeout > 1ms => sleep = 1ms 
A wait with timeout can take at least this sleep time even though the event is 
set or queue filled much faster.''' 
import threading 

event1 = threading.Event() 
event2 = threading.Event() 

def receiver(): 
    '''wait 4 event2, clear event2 and set event1.''' 
    while True: 
    event2.wait() 
    event2.clear() 
    event1.set() 

receiver_thread = threading.Thread(target = receiver) 
receiver_thread.start() 

def do_transaction(timeout): 
    '''Performs a transaction; clear event1, set event2 and wait for thread to set event1.''' 
    event1.clear() 
    event2.set() 
    event1.wait(timeout = timeout) 

while True: 
    # With timeout None this runs fast and CPU bound. 
    # With timeout set to some value this runs slow and not CPU bound. 
    do_transaction(timeout = 10.0) 

回答

2

查看threading.Condition類的wait()方法的源代碼,有兩種截然不同的代碼路徑。如果沒有超時,我們會永遠等待鎖,當我們獲得鎖時,我們會立即返回。

但是,由於超時,您不能簡單地等待鎖定,並且低級鎖定不會實現超時。因此,如果可以獲取鎖,每次睡眠檢查之後,代碼將會處於指數級更長的時間週期。從代碼中的相關評論:

# Balancing act: We can't afford a pure busy loop, so we 
# have to sleep; but if we sleep the whole timeout time, 
# we'll be unresponsive. The scheme here sleeps very 
# little at first, longer as time goes on, but never longer 
# than 20 times per second (or the timeout time remaining). 

所以在平均場景條件/事件不能是不是很短的時間內通知,你會看到一個25毫秒的延遲(隨機進入事件平均將抵達在睡眠結束前剩餘50ms的最大睡眠時間的一半)。