У меня проблемы с этой очередью:
import Queue
import threading
class test(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.request_queue = Queue.Queue()
def addtoqueue(self, item):
self.request_queue.put(item)
def run(self):
while True:
item = self.request_queue.get(True)
print item
Этот простой класс реализует поточную очередь. Вызов test::addtoqueue
добавит элемент в очередь. Поток ожидает добавления элемента в очередь - и сразу же печатает его и ждет следующего.
Моя проблема - выключение приложения. Каков наилучший способ прекратить поток? Я мог бы использовать условие, но как я могу ждать уведомления из условия или нового элемента в очереди?
Вы можете отправить яд в поток, чтобы убить его:
poison = None # something you wouldn't normally put in the Queue
class test(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.request_queue = Queue.Queue()
def kill(self):
self.addtoqueue(poison)
def addtoqueue(self, item):
self.request_queue.put(item)
def run(self):
while True:
item = self.request_queue.get(True)
if item is poison:
# do stuff
return # end thread
print item
Сделайте простую вещь, которая могла бы работать, что в данном случае может быть Стражем. И хотя threading
был вдохновлен библиотекой потоков Java, в Python простейшая вещь не делает что-то вроде Java и наследует от threading.Thread
, а передает функцию и ее аргументы в threading.Thread()
:
DONE = object() # Sentinel
def run(queue):
while True:
item = queue.get()
queue.task_done()
if item is DONE:
break
print item
request_queue = Queue.Queue()
some_thread = Thread(target=run, args=(request_queue,))
some_thread.start()
request_queue.put('hey')
request_queue.put('joe')
request_queue.put(DONE)
Я бы изменил условие в вашем цикле while, чтобы он проверил локальную переменную. Добавить добавить kill-switch, чтобы внешний процесс закрыл поток. Вероятно, вы должны расширить kill_me
, чтобы удалить объект и его Очередь красивым способом (например, если вы хотите сохранить очередь в следующий раз при запуске).
Изменить. Я также добавил переменную has_finished
, поэтому kill_me
должен блокировать основной поток процесса. Это должно позволить потоку выйти, прежде чем возвращаться к основному потоку.
У меня могут быть сложные вещи;)
class test(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.request_queue = Queue.Queue()
self.is_running = True
self.has_finished = False
def addtoqueue(self, item):
self.request_queue.put(item)
def kill_me(self):
self.is_running = False
while not self.has_finished:
pass
def run(self):
while self.is_running:
item = self.request_queue.get(True)
print item
self.has_finished = True
self.request_queue.get
блокирует, так что если он никогда не будет проверятьself.is_running
если он действительно был установлен вFalse
.