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