并发单例类Python

时间:2018-01-05 09:52:08

标签: python multithreading singleton

我试图创建一个由不同线程同时添加的字典。为此,我创建了一个包含字典实例的单例类。要访问这个字典,我想要一个信号量对象(因为不同的线程的传入键值对是不同的),它允许多个线程一次添加到字典中。

我在python中的尝试如下:

class recipeDict :

     initializationLock = threading.lock()
     semaphore = threading.Semaphore(10)
     dictInstance = None

     def _instance(cls):
         if not cls.dictInstance:
              with cls.initalizationLock:
                   if not cls.dictInstance:
                        dictInstance = dict()
         semaphore.acquire()
         try:
             return dictInstance
         finally:
             semaphore.release()

如果我的目标是让每个线程(25个线程)调用recipeDict并访问里面包含的字典(添加到它),然后释放信号量,这是一个合适的实现吗?

1 个答案:

答案 0 :(得分:0)

首先,为单身目的创建一个元类:

class Singleton(type):
    """
    An metaclass for singleton purpose. Every singleton class should inherit from this class by 'metaclass=Singleton'.
    """
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

其次,创建一个从dict扩展的类,并将metaclass设置为Singleton

class RecipeDict(dict, metaclass=Singleton):
    semaphore = Semaphore()

最后,实施自定义__getitem____setitem__

class RecipeDict(dict, metaclass=Singleton):
    semaphore = Semaphore()

    def __getitem__(*args, **kwargs):
        with semaphore:
            super().__getitem__(*args, **kwargs)

    def __setitem__(*args, **kwargs):
        with semaphore:
            super().__setitem__(*args, **kwargs)

但实际上,在python中从dict 获取和设置项目是线程安全的。

参考:http://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htm