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)
精彩评论