for more on program exits and daemonic threads (and other scary topics!placing callbacks on queues in the prior section' examplesthe data placed on the queue is always string that' sufficient for simple applications where there is just one type of producer if you may have many different kinds of threads producing many different types of results running at oncethoughthis can become difficult to manage you'll probably have to insert and parse out some sort of type or action information in the string so that the gui knows how to process it imagine an email clientfor instancewhere multiple sends and receives may overlap in timeif all threads share the same single queuethe information they place on it must somehow designate the sort of event it represents-- downloaded mail to displaya progress indicator updatea successful send completionand so on this isn' entirely hypotheticalwe'll confront this exact issue in ' pymailgui luckilyqueues support much more than just strings--any type of python object can be placed on queue perhaps the most general of these is callable objectby placing function or other callable object on the queuea producer thread can tell the gui how to handle the message in very direct way the gui simply calls the objects it pulls off the queue since threads all run within the same process and memory spaceany type of callable object works on queue--simple functionslambdasand even bound methods that combine function with an implied subject object that gives access to state information and methods any updates performed by the callback object update state shared across the entire process because python makes it easy to handle functions and their argument lists in generic fashionthis turns out to be easier than it might sound example - for instanceshows one way to throw callbacks on queue that we'll be using in for pymailgui this module comes with handful of tools its threadcounter class can be used as shared counter and boolean flag (for exampleto manage operation overlapthe real meat herethoughis the queue interface functions--in shortthey allow clients to launch threads which queue their exit actionsto be dispatched in the main thread by timer loop in some ways this example is just variation on those of the prior section--we still run timer loop here to pull items off the queue in the main thread for both responsiveness and efficiencythis timer loop pulls at most items on each timer eventnot just one (which may take too long or incur overheads for short timer delay)and not all queued (which may block indefinitely when many items are produced quicklywe'll leverage this per-event batching feature to work through many progress updates in pymailgui without having to devote cpu resources to quick timer events that are normally unnecessary gui coding techniques