Thread specific singleton
jhnsmth at gmail.com
jhnsmth at gmail.com
Mon Jun 12 11:14:05 EDT 2006
Gabriele Farina wrote:
> Hi,
>
> I'm tring to implement a Singleton object that should be specific for
> every thread who create it, not global.
> I tried a solution that seems to work, but I have a very poor knowledge
> of concurrent programming, so I'd like someone to help me find some
> problems in my implementation.
>
> Here is the code:
>
> -------------------------------------------------------------
>
> import thread
>
> class ThreadLock(object):
>
> locks = {}
>
> def __new__(cls):
> id = thread.get_ident()
> try:
> lock = cls.locks[id]
> except KeyError:
> lock = thread.allocate_lock()
> cls.locks[id] = lock
>
> return lock
>
> @classmethod
> def clear(cls, id=None):
> """ Clear the lock associated with a given id.
>
> If the id is None, thread.get_ident() is used.
> """
>
> if id is None:
> id = thread.get_ident()
> try:
> del cls.locks[id]
> except KeyError:
> pass
>
> class ThreadedSingleton(object):
>
> pool = {}
>
> def __new__(cls, *args, **kw):
> lock = ThreadLock()
> lock.acquire()
>
> id = thread.get_ident()
> try:
> obj = cls.pool[id]
> except KeyError:
> obj = object.__new__(cls, *args, **kw)
> if hasattr(obj, '__init_singleton__'):
> obj.__init_singleton__(*args, **kw)
> cls.pool[id] = obj
>
> lock.release()
>
> return obj
>
> def __del__(self):
> id = thread.get_ident()
> ThreadLock.clear(id)
> try:
> del cls.pool[id]
> except KeyError:
> pass
>
> if __name__ == '__main__':
>
> import time
> import random
>
> class Specific(ThreadedSingleton):
>
> def __init_singleton__(self):
> print "Init singleton"
> self.a = None
>
> def test(a):
> s = Specific()
> s.a = a
> print "%d: %s" %(thread.get_ident(), Specific().a)
> time.sleep(1)
> print "%d: %s" %(thread.get_ident(), Specific().a)
> time.sleep(random.randint(1, 5))
> print "%d: %s" %(thread.get_ident(), Specific().a)
> time.sleep(2)
> print "%d: %s" %(thread.get_ident(), Specific().a)
>
> for x in range(4):
> thread.start_new_thread(test, (x, ))
>
> time.sleep(10)
>
> -------------------------------------------------------------
>
> using the thread module should be fine even if threads are created
> trought the threading module, right ?
>
> Thanks,
> Gabriele
import thread
class Singleton:
pass
singletons = {}
def get_singleton():
ident = thread.get_ident()
try:
singleton = singletons[ident]
except KeyError:
singleton = Singleton()
singletons[ident] = singleton
return singleton
More information about the Python-list
mailing list