std::mutex und std::recursive_mutex



  • Gibt es Fälle in denen std::recursive_mutex schlecht zu wählen wäre über std::mutex?
    (Die NICHT! Performance basiert sind)

    Weil mir aufgefallen ist, dass ich inflationär std::recursive_mutex verwende, weil ich dann gar nicht mehr über deadlocks durch sequenzielles locken in dem selben Thread nachdenken muss und gefühlt sicherer bin keine deadlocks zu übersehen.
    Aber gibt es noch ein Haken an den ich grad nicht denke?



  • Etwas OT:

    Das hört sich für mich an wie "Ich hab hier alten Code, der niemals fürs Mutithreading gedacht war. Mit Threads stürzt der ab. Da schmeisse ich solange Mutexes drauf, bis es nicht mehr abstürzt". Das kann nicht gut gehen.



  • @5cript sagte in std::mutex und std::recursive_mutex:

    Aber gibt es noch ein Haken an den ich grad nicht denke?

    Ja: Condition-Variablen.

    void Foo::gun() {
        std::lock_guard lock{m_mutex};
        // ...
        foot();
        // ...
    }
    
    void Foo::foot() {
        std::lock_guard lock{m_mutex};
        // ...
        while (!blah)
            m_condition.wait(lock);
        // ...
    }
    

    Da die Mutex 2x gelockt wurde, aber von m_condition.wait(lock); nur 1x entsperrt wird, bleibt sie gesperrt. Ein anderer Thread der etwas am Zustand ändern könnte um blah wahr zu machen, müsste dazu auch erst die Mutex locken. Kann er aber nicht, weil sie ja immer noch gesperrt ist. => Deadlock

    ps: Das blöde dabei ist, dass es nicht notwendigerweise sofort auffällt. So lange blah immer wahr ist wenn foot aus gun aufgerufen wird funktioniert ja alles wunderbar. Wenn du dagegen nicht-rekursive Mutexen verwendest kannst du damit kaum Fehler machen die nicht sofort auffallen -- zumindest wenn du überhaupt irgendwelche Coverage für den Code-Pfad hast.



  • @manni66
    Ist eher, dass ich irgendwas in einer Klasse schützen will. Und die Funktionen die es verwenden (und locken) rufen sich dann einander auf.


Log in to reply