问题
It seems
import Queue
Queue.Queue().get(timeout=10)
is keyboard interruptible (ctrl-c) whereas
import Queue
Queue.Queue().get()
is not. I could always create a loop;
import Queue
q = Queue()
while True:
try:
q.get(timeout=1000)
except Queue.Empty:
pass
but this seems like a strange thing to do.
So, is there a way of getting an indefinitely waiting but keyboard interruptible Queue.get()?
回答1:
Queue
objects have this behavior because they lock using Condition
objects form the threading
module. So your solution is really the only way to go.
However, if you really want a Queue
method that does this, you can monkeypatch the Queue
class. For example:
def interruptable_get(self):
while True:
try:
return self.get(timeout=1000)
except Queue.Empty:
pass
Queue.interruptable_get = interruptable_get
This would let you say
q.interruptable_get()
instead of
interruptable_get(q)
although monkeypatching is generally discouraged by the Python community in cases such as these, since a regular function seems just as good.
回答2:
This may not apply to your use case at all. But I've successfully used this pattern in several cases: (sketchy and likely buggy, but you get the point).
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()
来源:https://stackoverflow.com/questions/212797/keyboard-interruptable-blocking-queue-in-python