Memberfunktionen "an sich" thread safe?



  • Hallo,

    angenommen ich hab ein globales Objekt, auf das von mehreren threads aus zugegriffen wird:

    struct Foo
    {
        int i = 0;
        void bar() { ++i; }
    } foo;
    
    void thread1_func() { foo.bar(); }
    void thread2_func() { foo.bar(); }
    // ...
    void threadn_func() { foo.bar(); }
    

    Reicht es dann, in Foo::bar einen mutex zu benutzen um das Ganze thread-safe zu machen? Oder benötige ich in jeder threadx_func einen mutex vor dem foo.bar() Aufruf?

    Sprich kann schon das Aufrufen alleine Probleme machen oder wirklich erst das inkrementieren der Member-Variable?



  • Erst der Zugriff auf die Variable ist unsicher.



  • Ok, alles klar, Danke 👍



  • Statt einem mutex würde ich in deinem Fall aber eher ein std::atomic int verwenden.



  • Jo, war nur ein abstraktes Beispiel das keinen direkten Realitätsbezug hat.



  • Du musst extern die Lebenszeit des foo Objekts garantieren können. Also das darf nicht zerstört werden während noch eine Memberfunktion läuft. Und es muss vollständig konstruiert sein bevor man die Memberfunktion aufruft*.

    Davon abgesehen kannst du dir für diese Frage den Aufruf einer Memberfunktion vorstellen wie den Aufruf einer freien Funktion, der du als zusätzliches Argument nen Zeiger auf das Objekt mitgibst.
    Und da das übergeben eines Zeigers auf ein Ding kein Race mit der Verwendung des Dings selbst erzeugt, muss man auch nicht von aussen "vor" dem Aufruf synchronisieren.

    *
    Vereinfacht gesagt.
    Es sollte OK sein eine Memberfunktion in einem anderen Thread ausführen zu lassen während ein Objekt "halb" konstruiert ist, also während z.B. ein Basisklassen-Ctor läuft. Sofern man dabei sicherstellt dass die Memberfunktion fertig gelaufen ist bevor der Basisklassen-Ctor verlassen wird. Das Objekt darf halt den Typ nicht wechseln während die Memberfunktion läuft, zumindest nicht wenn die Memberfunktion virtual ist. Das aber nur der Vollständigkeit halber.



  • hustbaer schrieb:

    Davon abgesehen kannst du dir für diese Frage den Aufruf einer Memberfunktion vorstellen wie den Aufruf einer freien Funktion, der du als zusätzliches Argument nen Zeiger auf das Objekt mitgibst.
    Und da das übergeben eines Zeigers auf ein Ding kein Race mit der Verwendung des Dings selbst erzeugt, muss man auch nicht von aussen "vor" dem Aufruf synchronisieren.

    Genau da war ich mir unsicher, weil man ja den Pointer benutzt um zu modifizieren. Umso besser dass das geht, dann kann ich das alles zentral und nur einmal machen 🙂


Anmelden zum Antworten