threadQ: Queues providing threadsafe access to non-threadsafe objects via serialization of method calls.
Usage pattern:
import boodebr.util.threadQ as tQ
# a non-threadsafe object class Foo(object): ...
# start queue on namespace 'foo' which will # produce wrapped versions of 'Foo' objects tQ.start('foo', Foo)
# create as many wrapped Foo objects as you need. # objects can be safely shared by multiple threads. foo = threadQ.QProxyObj('foo')
# when finished with queue, don't forget to shut it down # or your program will hang tQ.shutdown('foo')
Usage Notes
Queues are for serialization of calls, not locking. If you need to make several method calls atomically, you have to do your own locking. These queues only guarantee that no more than one thread will call an object method at a time.
Queues wrap methods not attributes. Attempting to get/set an attribute through the proxy object will not work.
Classes
QProxyObj(object)
Methods
__getattr__(self, name)
__init__(self, ns, args=(), kwargs={})
Create an object from the given namespace with a threadsafe wrapper.
Inputs
ns
Namespace to create object from (must have been previously started via start(ns)
args,kwargs
Arguments to pass to namespace factory function to create object.
Returns new object. Returned object can be safely shared between multiple threads. The proxy object will have all the same methods as the wrapped object. Attribute access is not possible.
Functions
start(ns, factory)
Begin a thread command queue for the given namespace.
Inputs
ns
Namespace (string)
factory
Factory function that creates objects for this namespace. Factory function takes any number of caller-defined parameters — you will pass the args when you create a QProxyObj
shutdown(ns)
Stop either a single thread by passing its namespace, or shutdown all threads by passing ns=None.
Once you call start(ns) you must call shutdown(ns) before your application exits, else your application will hang on exit.
You may call shutdown(ns) multiple times without error.