【问题标题】:Concurrent Singleton Class Python并发单例类 Python
【发布时间】:2018-01-05 18:10:18
【问题描述】:

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

我在 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 并访问其中包含的字典一段时间(添加到其中),然后释放信号量,这是一个合适的实现吗?

【问题讨论】:

  • 为什么要让它成为单例?如果这个对象有用,为什么要拒​​绝为每个应用程序实例化多个对象?似乎没有任何理由。正如 Sraw 在他的回答中指出的那样,字典访问已经是线程安全的,所以实际上你根本不需要做任何事情。

标签: python multithreading singleton


【解决方案1】:

首先,为单例创建一个元类:

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扩展的类并将元类设置为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)

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

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

【讨论】:

  • 你能解释一下什么是元类吗?在学习了一段时间 Java 之后,我才重新开始使用 python。
  • 元类是类的类。总之,类控制如何创建实例,元类控制如何创建类。
猜你喜欢
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多