Seite 1 von 1
Threadsicheres Singleton
Verfasst: Donnerstag 3. September 2009, 16:39
von snafu
Den Mechanismus hat sicher schon der ein oder andere gesehen, aber ich glaube es gibt noch keinen eigenen Thread dazu.
Code: Alles auswählen
import threading
class Singleton(object):
"""A thread-safe class acting like a singleton"""
_instance = None
_lock = threading.Lock()
def __new__(cls, *args, **kwargs):
if not cls._instance:
with cls._lock:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
Code: Alles auswählen
In [1]: from singleton import Singleton
In [2]: s1 = Singleton()
In [3]: s2 = Singleton()
In [4]: s1 is s2
Out[4]: True
Re: Threadsicheres Singleton
Verfasst: Donnerstag 3. September 2009, 18:30
von Defnull
Dein thread-safe Singleton ist nicht thread-safe, wenn es zwischen Zeile 9 und 10 zu einem Kontext-Wechsel kommt. Es sollte so aus sehen:
Code: Alles auswählen
import threading
class Singleton(object):
"""A thread-safe class acting like a singleton"""
_instance = None
_lock = threading.Lock()
def __new__(cls, *args, **kwargs):
with cls._lock:
if not cls._instance:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
Verfasst: Donnerstag 3. September 2009, 20:17
von theliquidwave
Kann mir mal jemand genau erklären, was ein Singleton ist und warum der jetzt Thread-sa
fe ist?
Danke

Verfasst: Donnerstag 3. September 2009, 20:25
von sma
Ein Singleton ist das einzige Exemplar einer Klasse. Oder anders ausgedrückt, alle Exemplare der Klasse sind nicht nur gleich sondern auch identisch.
Und threadsafe ist nicht das Singleton-Objekt, sondern der Konstruktor `__new__` der beim ersten Aufruf das Objekt erzeugt - genau einmal und nicht öfters.
Stefan
Verfasst: Donnerstag 3. September 2009, 20:26
von Defnull
Verfasst: Donnerstag 3. September 2009, 23:12
von snafu
Ist es eigentlich sinnvoll, dass ein Singleton Argumente annehmen kann? Denn schließlich verschwinden ja jegliche Argumente, die nach dem ersten Bau übergeben werden, ohnehin sang- und klanglos im Nirvana. Ist es vielleicht besser, einen anderen Weg zu gehen und eine Exception zu werfen, sobald versucht wird, ein Singleton zum zweiten Mal zu instanzieren? Welcher Weg wäre hier zu bevorzugen?
@Chrisber: Und um das gerade Erläuterte zu gewährleisten, ist der Trick hier, dass sich sozusagen in den Erstellungsprozess der Klasse eingemischt wird. Es wird diesmal nicht mit den Attributen des Exemplars gearbeitet, wie man es häufig in der __init__-Methode einer Klasse findet, sondern direkt mit den Klassenattributen. Die überschriebene __new__-Methode, welche noch vor __init__ aufgerufen wird, prüft, ob bereits ein Exemplar erstellt wurde. Wenn nicht, wird eins erstellt und an das Attribut _instance gebunden und dieser Wert gilt nun dauerhaft. Falls es schon ein Exemplar gibt - _instance also nicht mehr mit None belegt ist -, passiert nichts und es bleibt somit beim zuerst erstellten Exemplar. Zuletzt wird dieses dann zurückgeliefert.
Verfasst: Freitag 4. September 2009, 11:51
von snafu
Das was ich mit den Argumenten gesagt hab, erscheint mir immer schlüssiger. Dann vielleicht doch besser so:
Code: Alles auswählen
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if args or kwargs:
raise TypeError, 'Singleton does not take any argument'
if not cls._instance:
cls._instance = object.__new__(cls)
return cls._instance