Каков наилучший способ завершить этот поток при вызове функции? - PullRequest
1 голос
/ 30 апреля 2011

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

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

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

Ответы [ 3 ]

1 голос
/ 30 апреля 2011

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

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 голос
/ 30 апреля 2011

Делай самое простое, что могло бы сработать - в данном случае это может быть Страж. И хотя 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 голос
/ 30 апреля 2011

Я бы изменил условие в вашем цикле while, чтобы он проверял локальную переменную.Добавить добавить kill-switch, чтобы позволить внешнему процессу завершить работу потока.Вам, вероятно, следует расширить kill_me, чтобы утилизировать объект и его Очередь хорошим способом (например, если вы хотите сохранить Очередь при следующем запуске).

Редактировать IТакже добавлена ​​переменная 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...