Skip to content

Commit aa3e9c4

Browse files
authored
feat(singleton): ensure singleton thread safety and no performance degradation (#205)
1 parent fb09282 commit aa3e9c4

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

internlm/utils/common.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import inspect
66
import os
77
import random
8+
import threading
89
from abc import ABC, abstractmethod
910
from contextlib import contextmanager
1011
from datetime import datetime
@@ -169,18 +170,27 @@ def __call__(self, batch_count):
169170

170171
class SingletonMeta(type):
171172
"""
172-
Singleton Meta.
173+
Thread-safe Singleton Meta with double-checked locking.
174+
Reference: https://en.wikipedia.org/wiki/Double-checked_locking
173175
"""
174176

175177
_instances = {}
178+
_lock = threading.Lock()
176179

177180
def __call__(cls, *args, **kwargs):
181+
# First check (without locking) for performance reasons
178182
if cls not in cls._instances:
179-
cls._instances[cls] = super().__call__(*args, **kwargs)
183+
# Acquire a lock before proceeding to the second check
184+
with cls._lock:
185+
# Second check with lock held to ensure thread safety
186+
if cls not in cls._instances:
187+
instance = super().__call__(*args, **kwargs)
188+
cls._instances[cls] = instance
180189
else:
181190
assert (
182191
len(args) == 0 and len(kwargs) == 0
183-
), f"{cls.__name__} is a singleton class and a instance has been created."
192+
), f"{cls.__name__} is a singleton class and an instance has been created."
193+
184194
return cls._instances[cls]
185195

186196

0 commit comments

Comments
 (0)