架构设计
模块结构
singleton.py
├── SingletonMeta (元类)
│ ├── __new__
│ ├── __call__ (实例创建控制)
│ ├── reset_singleton()
│ ├── get_instance()
│ └── has_instance()
│
└── singleton (装饰器函数)
└── 创建 SingletonClass类图
┌─────────────────────────────────────────────────────────────────┐
│ SingletonMeta │
│ (metaclass) │
├─────────────────────────────────────────────────────────────────┤
│ + _singleton_lock: threading.Lock │
│ + _singleton_instance: Optional[Any] = None │
├─────────────────────────────────────────────────────────────────┤
│ + __new__(mcs, name, bases, namespace, **kwargs): type │
│ + __call__(cls, *args, **kwargs): Any │
│ + reset_singleton(cls) -> None │
│ + get_instance(cls) -> Optional[Any] │
│ + has_instance(cls) -> bool │
└─────────────────────────────────────────────────────────────────┘
│
│ creates
▼
┌─────────────────────────────────────────────────────────────────┐
│ singleton (decorator) │
├─────────────────────────────────────────────────────────────────┤
│ Input: cls: type │
│ Output: SingletonClass (with SingletonMeta as metaclass) │
└─────────────────────────────────────────────────────────────────┘
│
│ decorates
▼
┌─────────────────────────────────────────────────────────────────┐
│ SingletonClass │
│ (user's class) │
├─────────────────────────────────────────────────────────────────┤
│ (inherits from decorated class) │
│ (uses SingletonMeta as metaclass) │
│ (preserves __name__, __qualname__, __doc__) │
└─────────────────────────────────────────────────────────────────┘实例创建流程
Client 调用 MyClass()
│
▼
┌───────────────────────────┐
│ MyClass.__call__() │
│ (由 SingletonMeta 定义) │
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ _singleton_instance │
│ is None? │
└───────────┬───────────────┘
│
┌──────┴──────┐
Yes No
│ │
▼ ▼
┌─────────┐ ┌─────────────────┐
│ 获取锁 │ │ 返回已有实例 │
└────┬────┘ └─────────────────┘
│
▼
┌───────────────────────────┐
│ _singleton_instance │
│ is None? (再次检查) │
└───────────┬───────────────┘
│
┌──────┴──────┐
Yes No
│ │
▼ ▼
┌─────────┐ ┌─────────────────┐
│ 创建实例 │ │ 返回已有实例 │
└────┬────┘ └─────────────────┘
│
▼
┌───────────────────────────┐
│ 调用 super().__call__() │
│ 创建实际实例 │
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ 存储到 _singleton_instance│
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ 释放锁 │
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ 返回实例 │
└───────────────────────────┘重置流程
Client 调用 MyClass.reset_singleton()
│
▼
┌───────────────────────────┐
│ 获取类锁 │
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ _singleton_instance = │
│ None │
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ 释放锁 │
└───────────┬───────────────┘
│
▼
┌───────────────────────────┐
│ 下次调用将创建新实例 │
└───────────────────────────┘装饰器实现
python
def singleton(cls: type) -> type:
class SingletonClass(cls, metaclass=SingletonMeta):
pass
SingletonClass.__name__ = cls.__name__
SingletonClass.__qualname__ = cls.__qualname__
SingletonClass.__doc__ = cls.__doc__
return SingletonClass执行步骤:
@singleton 装饰器应用
│
▼
┌───────────────────────────────────┐
│ 1. 创建新类 SingletonClass │
│ - 继承原 cls │
│ - 使用 SingletonMeta 元类 │
└───────────┬───────────────────────┘
│
▼
┌───────────────────────────────────┐
│ 2. 复制元信息 │
│ __name__ = cls.__name__ │
│ __qualname__ = cls.__qualname__│
│ __doc__ = cls.__doc__ │
└───────────┬───────────────────────┘
│
▼
┌───────────────────────────────────┐
│ 3. 返回 SingletonClass │
│ (原类已被包装) │
└───────────────────────────────────┘元类 __new__ 实现
python
def __new__(mcs, name, bases, namespace, **kwargs):
cls = super().__new__(mcs, name, bases, namespace, **kwargs)
cls._singleton_lock = threading.Lock()
cls._singleton_instance = None
return cls设计说明:
_singleton_lock: 每个类独立的锁,支持多线程_singleton_instance: 类属性存储单例实例- 在
__new__初始化,而非__init__,确保线程安全
并发安全性分析
竞态条件场景
线程 A 线程 B
─────────────────────────────────────────
MyClass()
检查: instance is None ✓
获取锁
创建实例
释放锁
返回实例
MyClass()
检查: instance is None ✓
获取锁
检查: instance is None (已创建)
释放锁
返回已有实例 ✓为什么每个类有独立锁?
python
# 正确:类级别锁
class SingletonMeta(type):
def __new__(mcs, name, bases, namespace, **kwargs):
cls = super().__new__(mcs, name, bases, namespace, **kwargs)
cls._singleton_lock = threading.Lock() # 每个类独立
cls._singleton_instance = None
return cls
# 错误:共享锁(会导致死锁)
_global_lock = threading.Lock() # 所有单例共享继承行为
python
@singleton
class Base:
pass
class Child(Base):
pass
b = Base() # 单例实例
c = Child() # 同样是单例实例
assert b is c # True原因: Child 没有使用 @singleton 装饰器,但继承了 Base,而 Base 使用了 SingletonMeta 作为元类。
注意: 如果希望子类也有独立的单例,需要单独装饰:
python
@singleton
class Base:
pass
@singleton
class Child(Base):
pass
b = Base() # 实例 1
c = Child() # 实例 2 (不同单例)
assert b is not c # True