Каков наилучший способ завершить этот поток при вызове функции?

1

У меня проблемы с этой очередью:

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 добавит элемент в очередь. Поток ожидает добавления элемента в очередь - и сразу же печатает его и ждет следующего.

Моя проблема - выключение приложения. Каков наилучший способ прекратить поток? Я мог бы использовать условие, но как я могу ждать уведомления из условия или нового элемента в очереди?

Теги:
multithreading
queue
terminate

3 ответа

1
Лучший ответ

Вы можете отправить яд в поток, чтобы убить его:

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
1

Сделайте простую вещь, которая могла бы работать, что в данном случае может быть Стражем. И хотя 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)
1

Я бы изменил условие в вашем цикле 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
  • 1
    Хммм ... хотя одна проблема. self.request_queue.get блокирует, так что если он никогда не будет проверять self.is_running если он действительно был установлен в False .
  • 0
    @ Джордж Отредактирован!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню