开发者

What is the best way to end this thread when a function is called?

I'm having a bit of trouble with this queue:

import Queue
import threading

class test(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.request_queue = Queue.Queue()

    def addtoqueue(se开发者_JAVA技巧lf, item):
        self.request_queue.put(item)

    def run(self):
        while True:
            item = self.request_queue.get(True)
            print item

This simple class implements a threaded queue. Calling test::addtoqueue will append an item to the queue. The thread waits for an item to be added to the queue - and immediately prints it and waits for the next thing.

My problem is application shutdown. What is the best way to terminate the thread? I could use a Condition, but how could I wait for either a notification from the Condition or a new item in the queue?


You can send some poison to the thread to kill it:

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


I'd alter the condition in your while loop so that it checked for a local variable. Add add a kill-switch to allow an external process to shut the thread down. You should probably extend kill_me to dispose of the object and its Queue in a nice way (eg if you want to store the Queue for the next time it's run).

Edit I've also added a has_finished variable in there so kill_me should block the main process thread. This should allow the thread to exit before handing back to the main flow.

I may have overcomplicated things ;)

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


Do The Simplest Thing That Could Possibly Work - which, in this case, might be a Sentinel. And although threading was inspired by Java's threading library, in Python the simplest thing is not do things Java-like and inherit from threading.Thread, but to pass a function and its arguments to 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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜