14.3. The Queue ModuleThe Queue module supplies first-in, first-out (FIFO) queues that support multithread access, with one main class and two exception classes.
14.3.1. Methods of Queue InstancesAn instance q of class Queue supplies the following methods.
Queue offers a good example of the idiom "It's easier to ask forgiveness than permission" (EAFP), covered in "Error-Checking Strategies" on page 134. Due to multithreading, each nonmutating 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" 14.3.2. Customizing Class Queue by SubclassingIf you require the intrinsically thread-safe behavior of class Queue.Queue but do not want a FIFO queuing discipline, you may customize Queue.Queue by subclassing, and you need to override some or all of the hook methods that Queue.Queue provides for the purpose: _qsize, _empty, _full, _put, and _get. Each has semantics that correspond to the public method with the corresponding name, but they're simpler, with no worries about threading, timeouts, or error checking. The only one of them that takes an argument (besides the usual self) is _put (which takes as its argument the item to put on the queue). Queue.Queue ensures that hook methods will get called only in a state already made properly thread-safe (i.e., Queue.Queue's own methods ensure all the needed locking) and that hook methods need not worry about error-checking (for example, _get is called only when the queue is nonemptyi.e., when _empty has just returned a false result). For example, all it takes to make a thread-safe queue class with a LIFO queuing discipline is: import Queue class LIFOQueue(Queue.Queue): def _get(self): return self.queue.pop( ) which exploits the self.queue attribute, which Queue.Queue instances already have (an instance of type collections.deque, covered in "The collections Module" on page 173). |