Клавиатура прерывистой блокировки очереди в Python - PullRequest
12 голосов
/ 17 октября 2008

Кажется

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 ]

6 голосов
/ 17 октября 2008

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)

, хотя в таких случаях сообщество Python не поощряет monkeypatching, поскольку обычная функция кажется такой же хорошей.

4 голосов
/ 19 октября 2008

Это может не относиться к вашему варианту использования вообще. Но я успешно использовал этот шаблон в нескольких случаях: (отрывочный и, вероятно, глючный, но вы поняли суть).

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()
...