Threaded Program Architecture
A threaded program should always arrange for a single thread to deal with any given object or subsystem that is external to the program (such as a file, a database, a GUI, or a network connection). Having multiple threads that deal with the same external object can often cause unpredictable problems.
Whenever your threaded program
must deal with some external object, devote a thread to such
dealings, using a Queue object from which the
external-interfacing thread gets work requests that other threads
post. The external-interfacing thread can return results by putting
them on one or more other Queue objects. The
following example shows how to package this architecture into a
general, reusable class, assuming that each unit of work on the
external subsystem can be represented by a callable object:
import threading, Queue
class ExternalInterfacing(Threading.Thread):
def __init__(self, externalCallable, **kwds):
Threading.Thread.__init__(self, **kwds)
self.setDaemon(1)
self.externalCallable = externalCallable
self.workRequestQueue = Queue.Queue( )
self.resultQueue = Queue.Queue( )
self.start( )
def request(self, *args, **kwds):
"called by other threads as externalCallable would be"
self.workRequestQueue.put((args,kwds))
return self.resultQueue.get( )
def run(self):
while 1:
args, kwds = self.workRequestQueue.get( )
self.resultQueue.put(self.externalCallable(*args, **kwds))Once some ExternalInterfacing object
ei is instantiated, all other threads may now ...