调用函数时结束此线程的最佳方法是什么?

时间:2011-04-29 23:54:34

标签: python multithreading queue terminate

我在这个队列中遇到了一些麻烦:

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 个答案:

答案 0 :(得分: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 :(得分: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

答案 2 :(得分: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)