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()也能通过键盘中断呢?
2 个回答
4
这可能跟你的情况没什么关系。不过我在几个场合成功用了这个方法:(虽然有点不靠谱,可能还有bug,但你大概明白我的意思)。
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()
6
Queue
对象之所以这样工作,是因为它们使用了来自threading
模块的Condition
对象进行锁定。所以你的解决方案实际上是唯一可行的方式。
不过,如果你真的想要一个Queue
的方法来实现这个功能,你可以对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)
尽管在这种情况下,Python社区通常不鼓励使用猴子补丁,因为一个普通的函数似乎同样有效。