python-cookbook
python-cookbook copied to clipboard
Communicating between threads example
Hi!
In the Chapter 12: communicating between threads "Solution" section (bottom of p493) there is an example in which the Queue.task_done method is used along with Queue.join to wait for all items produced by the "producer" function to be consumed.
However (and unless I am misunderstanding), because the queue has no items in it before the threads start, unless the producer function immediately puts an item (before the q.join() executes in the main thread) into the queue, the queue will immediately join. For example, if you have something like:
from queue import Queue
from threading import Thread
import time
def producer(out_q):
time.sleep(5)
out_q.put('hello')
def consumer(in_q):
h = in_q.get()
print(h + ' world!')
in_q.task_done()
q = Queue()
t1 = Thread(target=producer, args=(q,))
t2 = Thread(target=consumer, args=(q,))
t1.start()
t2.start()
q.join()
print('q joined!')
You will see:
q joined!
hello world!
I guess the fix would be putting in an initial sentinel before starting the threads?
Love the book by the way!
This is a good observation. Another possible fix is to join with the producer thread before performing the task join operation. I'll make a note in text for errata.
Cheers Dave
Sent from cell
On Jun 15, 2013, at 1:11 PM, drewthepooh [email protected] wrote:
Hi!
In the Chapter 12: communicating between threads "Solution" section (bottom of p493) there is an example in which the Queue.task_done method is used along with Queue.join to wait for all items produced by the "producer" function to be consumed.
However (and unless I am misunderstanding), because the queue has no items in it before the threads start, unless the producer function immediately puts an item (before the q.join() executes in the main thread) into the queue, the queue will immediately join. For example, if you have something like:
from queue import Queue from threading import Thread import time
def producer(out_q): time.sleep(5) out_q.put('hello')
def consumer(in_q): h = in_q.get() print(h + ' world!') in_q.task_done()
q = Queue() t1 = Thread(target=producer, args=(q,)) t2 = Thread(target=consumer, args=(q,))
t1.start() t2.start()
q.join() print('q joined!') You will see:
q joined! hello world! I guess the fix would be putting in an initial sentinel value before starting the threads?
— Reply to this email directly or view it on GitHub.