2008-10-17 137 views
12

看來鍵盤中斷的阻塞隊列在Python

import Queue 

Queue.Queue().get(timeout=10) 

是鍵盤中斷(CTRL-C),而

import Queue 

Queue.Queue().get() 

不是。我總是可以創建一個循環;

import Queue 
q = Queue() 

while True: 
    try: 
     q.get(timeout=1000) 
    except Queue.Empty: 
     pass 

但這似乎是一件奇怪的事情。

那麼,有沒有辦法讓無限期的等待,但鍵盤可中斷Queue.get()?

+0

線程是否可以用其他方式中斷? – fatuhoku 2013-10-17 16:57:10

+3

這是[Bug 1360](http://bugs.python.org/issue1360),它被關閉爲「不會修復」。建議的解決方法是在需要中斷時始終指定超時。 – dimo414 2015-06-18 18:24:12

回答

6

Queue對象具有此行爲,因爲它們使用Condition對象鎖定threading模塊。所以你的解決方案是唯一的出路。

但是,如果你真的想要一個Queue方法來做到這一點,你可以monkeypatch Queue類。例如:

def interruptable_get(self): 
    while True: 
     try: 
      return self.get(timeout=1000) 
     except Queue.Empty: 
      pass 
Queue.interruptable_get = interruptable_get 

這將讓你說

q.interruptable_get() 

,而不是

interruptable_get(q) 

雖然的monkeypatching由Python社區在這些情況下一般不提倡的,因爲常規的功能看起來一樣好。

4

這可能根本不適用於您的用例。但是我在幾種情況下成功地使用了這種模式:(粗略和可能的越野車,但你明白了)。

STOP = object() 

def consumer(q): 
    while True: 
     x = q.get() 
     if x is STOP: 
      return 
     consume(x) 

def main() 
    q = Queue() 
    c=threading.Thread(target=consumer,args=[q]) 

    try: 
     run_producer(q) 
    except KeybordInterrupt: 
     q.enqueue(STOP) 
    c.join()