Skip to content

Commit 7ef9160

Browse files
[Fix]: implement thread-safety singleton to avoid deadlock for very large-scale training scenarios (#5625)
* implement thread-safety singleton * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * refactor singleton implementation * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent bbb2c21 commit 7ef9160

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed
Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1+
import threading
2+
3+
14
class SingletonMeta(type):
25
"""
3-
The Singleton class can be implemented in different ways in Python. Some
4-
possible methods include: base class, decorator, metaclass. We will use the
5-
metaclass because it is best suited for this purpose.
6+
Thread-safe Singleton Meta with double-checked locking.
7+
Reference: https://en.wikipedia.org/wiki/Double-checked_locking
68
"""
79

810
_instances = {}
11+
_lock = threading.Lock()
912

1013
def __call__(cls, *args, **kwargs):
11-
"""
12-
Possible changes to the value of the `__init__` argument do not affect
13-
the returned instance.
14-
"""
14+
# First check (without locking) for performance reasons
1515
if cls not in cls._instances:
16-
instance = super().__call__(*args, **kwargs)
17-
cls._instances[cls] = instance
16+
# Acquire a lock before proceeding to the second check
17+
with cls._lock:
18+
# Second check with lock held to ensure thread safety
19+
if cls not in cls._instances:
20+
instance = super().__call__(*args, **kwargs)
21+
cls._instances[cls] = instance
1822
else:
1923
assert (
2024
len(args) == 0 and len(kwargs) == 0
21-
), f"{cls.__name__} is a singleton class and a instance has been created."
25+
), f"{cls.__name__} is a singleton class and an instance has been created."
26+
2227
return cls._instances[cls]

0 commit comments

Comments
 (0)