Thread specific singleton

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gabriele Farina

    #1

    Thread specific singleton

    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(obje ct):

    locks = {}

    def __new__(cls):
    id = thread.get_iden t()
    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_iden t() is used.
    """

    if id is None:
    id = thread.get_iden t()
    try:
    del cls.locks[id]
    except KeyError:
    pass

    class ThreadedSinglet on(object):

    pool = {}

    def __new__(cls, *args, **kw):
    lock = ThreadLock()
    lock.acquire()

    id = thread.get_iden t()
    try:
    obj = cls.pool[id]
    except KeyError:
    obj = object.__new__( cls, *args, **kw)
    if hasattr(obj, '__init_singlet on__'):
    obj.__init_sing leton__(*args, **kw)
    cls.pool[id] = obj

    lock.release()

    return obj

    def __del__(self):
    id = thread.get_iden t()
    ThreadLock.clea r(id)
    try:
    del cls.pool[id]
    except KeyError:
    pass

    if __name__ == '__main__':

    import time
    import random

    class Specific(Thread edSingleton):

    def __init_singleto n__(self):
    print "Init singleton"
    self.a = None

    def test(a):
    s = Specific()
    s.a = a
    print "%d: %s" %(thread.get_id ent(), Specific().a)
    time.sleep(1)
    print "%d: %s" %(thread.get_id ent(), Specific().a)
    time.sleep(rand om.randint(1, 5))
    print "%d: %s" %(thread.get_id ent(), Specific().a)
    time.sleep(2)
    print "%d: %s" %(thread.get_id ent(), Specific().a)

    for x in range(4):
    thread.start_ne w_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
  • Aahz

    #2
    Re: Thread specific singleton

    In article <448991d2$0$182 98$4fafbaef@rea der1.news.tin.i t>,
    Gabriele Farina <g.farina@html. it> wrote:[color=blue]
    >
    >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.[/color]

    Try using threading.local (), but you'll need 2.4 or later.
    --
    Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

    "I saw `cout' being shifted "Hello world" times to the left and stopped
    right there." --Steve Gonedes

    Comment

    • jhnsmth@gmail.com

      #3
      Re: Thread specific singleton


      Gabriele Farina wrote:[color=blue]
      > 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(obje ct):
      >
      > locks = {}
      >
      > def __new__(cls):
      > id = thread.get_iden t()
      > 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_iden t() is used.
      > """
      >
      > if id is None:
      > id = thread.get_iden t()
      > try:
      > del cls.locks[id]
      > except KeyError:
      > pass
      >
      > class ThreadedSinglet on(object):
      >
      > pool = {}
      >
      > def __new__(cls, *args, **kw):
      > lock = ThreadLock()
      > lock.acquire()
      >
      > id = thread.get_iden t()
      > try:
      > obj = cls.pool[id]
      > except KeyError:
      > obj = object.__new__( cls, *args, **kw)
      > if hasattr(obj, '__init_singlet on__'):
      > obj.__init_sing leton__(*args, **kw)
      > cls.pool[id] = obj
      >
      > lock.release()
      >
      > return obj
      >
      > def __del__(self):
      > id = thread.get_iden t()
      > ThreadLock.clea r(id)
      > try:
      > del cls.pool[id]
      > except KeyError:
      > pass
      >
      > if __name__ == '__main__':
      >
      > import time
      > import random
      >
      > class Specific(Thread edSingleton):
      >
      > def __init_singleto n__(self):
      > print "Init singleton"
      > self.a = None
      >
      > def test(a):
      > s = Specific()
      > s.a = a
      > print "%d: %s" %(thread.get_id ent(), Specific().a)
      > time.sleep(1)
      > print "%d: %s" %(thread.get_id ent(), Specific().a)
      > time.sleep(rand om.randint(1, 5))
      > print "%d: %s" %(thread.get_id ent(), Specific().a)
      > time.sleep(2)
      > print "%d: %s" %(thread.get_id ent(), Specific().a)
      >
      > for x in range(4):
      > thread.start_ne w_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[/color]

      import thread

      class Singleton:
      pass

      singletons = {}

      def get_singleton() :
      ident = thread.get_iden t()
      try:
      singleton = singletons[ident]
      except KeyError:
      singleton = Singleton()
      singletons[ident] = singleton
      return singleton

      Comment

      Working...