Meyers Singleton Threadsafe in gcc ?



  • Guten Abend und frohe Ostern,

    ich meine mich zu erinnern, hier im Forum gelesen zu haben, gcc würde garantieren, dass das sogenannte "Meyers Singleton" threadsafe ist. Nur finde ich gerade weder hier im Forum den Thread noch eine offizielle Quelle dafür.

    Frage: Gilt das für beide Formen des Meyers Singeltons, also für die mit Referenzen genauso wie die mit Pointern?

    Ich kenne nämlich zwei implementierungen der getInstance()-Funktion, die sich beide Meyers Singleton nennen:

    static Singleton* getInstance() {
        static Singleton instance;
        return &instance;
    }
    

    und mit Referenzen:

    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }
    

    Ich würde letztere bevorzugen und wüsste gerne, ob es eine offizielle Quelle dafür gibt, dass das in gcc threadsafe ist.

    Gruß,
    Philipp

    ...und viele dicke bunte Eier!



  • Wenn das für das eine gilt, dass auch für das andere. Eine Referenz ist nur eine andere Syntax für einen Zeiger.



  • PhilippM schrieb:

    Frage: Gilt das für beide Formen des Meyers Singeltons, also für die mit Referenzen genauso wie die mit Pointern?

    Ist es wirklich threadsafe im GCC? Falls es mit Zeigern threadsafe ist, gilt das auch für Referenzen und umgekehrt.

    TyRoXx schrieb:

    Eine Referenz ist nur eine andere Syntax für einen Zeiger.

    Das stimmt ja wohl definitiv nicht. Auch wenn du das vielleicht anders gemeint hast, kann so eine Aussage sehr irreführend sein.



  • Nexus schrieb:

    TyRoXx schrieb:

    Eine Referenz ist nur eine andere Syntax für einen Zeiger.

    Das stimmt ja wohl definitiv nicht. Auch wenn du das vielleicht anders gemeint hast, kann so eine Aussage sehr irreführend sein.

    Warum stimmt das denn nicht? Eine Referenz macht genau dasselbe wie ein Zeiger.



  • TyRoXx schrieb:

    Warum stimmt das denn nicht? Eine Referenz macht genau dasselbe wie ein Zeiger.

    Muss ich das hier echt erklären? 🙄

    Was ist mit Null?
    Mit Veränderbarkeit?
    Mit Initialisierung?
    Mit Objekt-Status?

    Alles semantische Unterschiede, welche für den Benutzer nicht egal sind!



  • Kann dir nicht zum gcc speziell was sagen, aber theoretisch muss der Compiler die Initialisierung des Singletons mit nem mutex schützen, ja.



  • Ja, threadsicher ... zumindest bei aktuellen Versionen, wenn Du es nicht explizit über -fno-threadsafe-statics ausschaltest. Ab welcher Version das so gemacht wird, müsstest Du mal in der Doku nachschauen. std::string aus libstdc++ hat ja inzwischen auch eine threadsichere copy-on-write Implementierung. In der kommenden C++ Version wird das auch alles so garantiert.

    Allerdings gibt's da noch ein kleines potentielles Problem bei diesem Ansatz: Die Objekte werden in irgendeiner Reihenfolge auch wieder zerstört. Wenn Du zwei Singletons hast, wobei das eine vom andern abhängt, kann das schon mal beim Programmende schief gehen -- nämlich dann, wenn das "falsche" zuersrt zerstört wird.

    Ohne da jetzt richtig viel drüber nachgedacht zu haben, würde ich sagen, es macht Sinn einen shared_ptr dafür anzulegen:

    shared_ptr<MySingleton> getInstante()
    {
      static shared_ptr<MySingleton> sp =
        make_shared<MySingleton>();
      return sp;
    }
    

    Solange es mindestens einen shared_ptr auf so ein Objekt gibt, während es noch benötigt wird, und es sonst keine Kreise von Verweisen gibt, sollte das alles sauber funktionieren -- auch das Aufräumen nachdem die main-Funktion fertig ist. Natürlich muss man beim Zugriff auf ein Singleton-Objekt, welches von mehreren Threads aus benutzt werden soll, auf Threadsicherheit achten -- das heißt: Mutexes und Locks benutzen.



  • Nexus schrieb:

    Was ist mit Null?
    Mit Veränderbarkeit?
    Mit Initialisierung?
    Mit Objekt-Status?

    Alles semantische Unterschiede, welche für den Benutzer nicht egal sind!

    Darum geht es hier doch gar nicht. Es geht darum, dass ein Zeiger auf Speicher zeigt und eine Referenz ebenfalls. Dabei verhalten sich beide am Ende gleich (siehe Anfangsfrage).



  • TyRoXx schrieb:

    Darum geht es hier doch gar nicht. Es geht darum, dass ein Zeiger auf Speicher zeigt und eine Referenz ebenfalls. Dabei verhalten sich beide am Ende gleich (siehe Anfangsfrage).

    Ja, meistens wird das wohl der Fall sein. Ich bestreite gar nicht, dass es hier keine Rolle spielt.

    Es geht mir darum, dass Sätze wie "Eine Referenz ist nur eine andere Syntax für einen Zeiger" oder "Eine Referenz macht genau dasselbe wie ein Zeiger" ohne Relativierung grober Unfug sind und jeden verunsichern, der mit der Materie noch nicht vertraut ist. Schliesslich sind Sprachmittel aus der Sicht des Programmierers zu betrachten; wie der kompilierten Assemblercode aussieht, steht nicht im Vordergrund. Und auf C++-Ebene sind Zeiger und Referenzen eben unterschiedliche Konzepte, und zwar nicht nur was die Syntax betrifft.



  • Siehe in meiner Signatur der Link über Singletons 🙂



  • evilissimo schrieb:

    Siehe in meiner Signatur der Link über Singletons 🙂

    Verstehe ich nicht. Steht da, ob "Meyers Singleton Threadsafe in gcc" sind?

    Lecker klingt vom GCC-Handbuch http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/C_002b_002b-Dialect-Options.html#C_002b_002b-Dialect-Options

    -fno-threadsafe-statics
    Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn't need to be thread-safe.


Anmelden zum Antworten