Mit POSIX können Mutexe rekursiv sein. Das bedeutet, dass derselbe Thread denselben Mutex zweimal sperren kann und nicht blockiert. Natürlich muss es auch zweimal entsperrt werden, sonst kann kein anderer Thread den Mutex erhalten. Nicht alle Systeme, die Pthreads unterstützen, unterstützen auch rekursive Mutexe. Wenn sie jedoch POSIX-konform sein möchten, müssen sie dies tun .
Andere APIs (höherwertige APIs) bieten normalerweise auch Mutexe an, die häufig als Sperren bezeichnet werden. Einige Systeme / Sprachen (z. B. Cocoa Objective-C) bieten sowohl rekursive als auch nicht rekursive Mutexe. Einige Sprachen bieten auch nur die eine oder andere an. Beispielsweise sind Mutexe in Java immer rekursiv (derselbe Thread kann zweimal für dasselbe Objekt "synchronisiert" werden). Abhängig davon, welche anderen Thread-Funktionen sie anbieten, ist es möglicherweise kein Problem, keine rekursiven Mutexe zu haben, da sie leicht selbst geschrieben werden können (ich habe rekursive Mutexe bereits selbst auf der Grundlage einfacherer Mutex- / Bedingungsoperationen implementiert).
Was ich nicht wirklich verstehe: Wofür sind nicht rekursive Mutexe gut? Warum sollte ich einen Thread-Deadlock haben wollen, wenn er denselben Mutex zweimal sperrt? Selbst Hochsprachen, die dies vermeiden könnten (z. B. Testen, ob dies zum Stillstand kommt, und Auslösen einer Ausnahme, wenn dies der Fall ist), tun dies normalerweise nicht. Sie lassen stattdessen den Thread blockieren.
Ist dies nur in Fällen der Fall, in denen ich es versehentlich zweimal und nur einmal entsperre und im Falle eines rekursiven Mutex ist es schwieriger, das Problem zu finden. Stattdessen muss es sofort blockiert werden, um festzustellen, wo die falsche Sperre angezeigt wird. Aber könnte ich nicht dasselbe tun, wenn beim Entsperren ein Sperrzähler zurückgegeben wird und in einer Situation, in der ich sicher bin, dass ich die letzte Sperre freigegeben habe und der Zähler nicht Null ist, kann ich eine Ausnahme auslösen oder das Problem protokollieren? Oder gibt es einen anderen, nützlicheren Anwendungsfall für nicht rekursive Mutexe, den ich nicht sehe? Oder ist es vielleicht nur Leistung, da ein nicht rekursiver Mutex etwas schneller sein kann als ein rekursiver? Ich habe dies jedoch getestet und der Unterschied ist wirklich nicht so groß.