[ Team LiB ] Previous Section Next Section

14.3 The Queue Module

The Queue module supplies first-in, first-out (FIFO) queues that support multithread access, with one main class and two exception classes.

Queue

class Queue(maxsize=0)

Queue is the main class for module Queue and is covered in the next section. When maxsize is greater than 0, the new Queue instance q is deemed full when q has maxsize items. A thread inserting an item with the block option, when q is full, suspends until another thread extracts an item. When maxsize is less than or equal to 0, q is never considered full, and is limited in size only by available memory, like normal Python containers.

Empty

Empty is the class of the exception that q.get(False) raises when q is empty.

Full

Full is the class of the exception that q.put(x,False) raises when q is full.

An instance q of class Queue supplies the following methods.

empty

q.empty(  )

Returns True if q is empty, otherwise False.

full

q.full(  )

Returns True if q is full, otherwise False.

get, get_nowait

q.get(block=True)

When block is False, get removes and returns an item from q if one is available, otherwise get raises Empty. When block is True, get removes and returns an item from q, suspending the calling thread, if need be, until an item is available. q.get_nowait( ) is like q.get(False). get removes and returns items in the same order as put inserted them (first in, first out).

put, put_nowait

q.put(item,block=True)

When block is False, put adds item to q if q is not full, otherwise put raises Full. When block is True, put adds item to q, suspending the calling thread, if need be, until q is not full. q.put_nowait(item) is like q.put(item,False).

qsize

q.qsize(  )

Returns the number of items that are currently in q.

Queue offers a good example of the idiom "it's easier to ask forgiveness than permission" (EAFP), covered in Chapter 6. Due to multithreading, each non-mutating method of q can only be advisory. When some other thread executes and mutates q, things can change between the instant a thread gets the information and the very next moment, when the thread acts on the information. Relying on the "look before you leap" (LBYL) idiom is futile, and fiddling with locks to try and fix things is a substantial waste of effort. Just avoid LBYL code such as:

if q.empty(  ): print "no work to perform"
else: x=q.get_nowait(  )

and instead use the simpler and more robust EAFP approach:

try: x=q.get_nowait(  )
except Queue.Empty: print "no work to perform"
    [ Team LiB ] Previous Section Next Section