Double-checked Sperren in C ++ 11? [Duplikat]

7

Hier ist ein Java-Beispielproblem von Ссылка

%Vor%

Es scheint, dass dies nicht sicher ist, weil # 3 die Instanz auf nicht null setzen kann, bevor der Konstruktor ausgeführt wird, also wenn ein anderer Thread die Instanz auf # 4 prüft, wird es nicht null sein und eine Instanz zurückgeben, die nicht richtig konstruiert wurde.

Scheinbar hilft die Verwendung einer Funktionsvariablen nicht, weil sie optimiert werden kann oder einfach so ausgeführt werden kann, dass der Wert auch auf Instanz gesetzt wird, wenn wir es nicht wollen.

Ich dachte, es wäre nicht der einfachste Weg, eine Funktion new Singleton(); zu haben, so dass sie abgeschlossen ist, bevor sie der Instanz zugewiesen wird. Nun ist das Problem, wie kann ich C ++ eine Funktion sagen, sollte nicht inline sein? Ich denke, Singleton* make_singleton() volatile sollte das tun, aber ich bin mir sicher, dass ich falsch liege.

    
R. Martinho Fernandes 07.05.2013, 06:22
quelle

2 Antworten

25

Ich werde die Singleton-Bits für eine Weile ignorieren und nehme an, dass du das für eine faule Initialisierung brauchst und nicht für dumme Dinge wie Singletons.

Ich schlage vor, das doppelt kontrollierte Sperren zu vergessen. C ++ bietet ein sehr nützliches Werkzeug für diese Art von Situation in Form von std::call_once , also nutze das .

%Vor%     
R. Martinho Fernandes 07.05.2013, 14:18
quelle
2

Dies ist genau die Art von Situation, für die Atomics entwickelt wurden. Wenn Sie das Ergebnis in einem atomaren Speicher speichern, wissen Sie, dass der Compiler keine kritischen Speicher oder Operationen nach der Festlegung des Atomwerts sequenzieren kann. Atomics dienen sowohl zum Emittieren von Prozessorbefehlsprimitiven, um die notwendige sequentielle Konsistenz sicherzustellen (z. B. für die Cachekohärenz über Kerne hinweg) als auch zum Erklären des Compilers, welche Semantik beibehalten werden muss (und daher die Arten von Neuordnungen, die er durchführen kann). Wenn Sie hier ein Atom verwenden, spielt es keine Rolle, ob die Funktion inlined ist, denn was auch immer den Compiler einbezieht, muss die Semantik des Atoms selbst erhalten.

Sie könnten auch interessiert sein, in std::call_once zu suchen, das auch für diese Situation entworfen wurde, und genauer gesagt für die Situation, in der mehrere Threads etwas benötigen, aber genau eine von ihnen sollte es tun.

    
Adam H. Peterson 07.05.2013 14:11
quelle