[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

The Python queue module implements this storage device. It provides a standard queue
data structure—a first-in first-out (fifo) list of Python objects, in which items are added
on one end and removed from the other. Like normal lists, the queues provided by this
module may contain any type of Python object, including both simple types (strings,
lists, dictionaries, and so on) and more exotic types (class instances, arbitrary callables
like functions and bound methods, and more).


Unlike normal lists, though, the queue object is automatically controlled with thread
lock acquire and release operations, such that only one thread can modify the queue
at any given point in time. Because of this, programs that use a queue for their cross-
thread communication will be thread-safe and can usually avoid dealing with locks of
their own for data passed between threads.


Like the other tools in Python’s threading arsenal, queues are surprisingly simple to
use. The script in Example 5-14, for instance, spawns two consumer threads that watch
for data to appear on the shared queue and four producer threads that place data on
the queue periodically after a sleep interval (each of their sleep durations differs to
simulate a real, long-running task). In other words, this program runs 7 threads (in-
cluding the main one), 6 of which access the shared queue in parallel.


Example 5-14. PP4E\System\Threads\queuetest.py


"producer and consumer threads communicating with a shared queue"


numconsumers = 2 # how many consumers to start
numproducers = 4 # how many producers to start
nummessages = 4 # messages per producer to put


import _thread as thread, queue, time
safeprint = thread.allocate_lock() # else prints may overlap
dataQueue = queue.Queue() # shared global, infinite size


def producer(idnum):
for msgnum in range(nummessages):
time.sleep(idnum)
dataQueue.put('[producer id=%d, count=%d]' % (idnum, msgnum))


def consumer(idnum):
while True:
time.sleep(0.1)
try:
data = dataQueue.get(block=False)
except queue.Empty:
pass
else:
with safeprint:
print('consumer', idnum, 'got =>', data)


if name == 'main':
for i in range(numconsumers):
thread.start_new_thread(consumer, (i,))
for i in range(numproducers):


Threads | 205
Free download pdf