POSIX permite que los mutexes sean recursivos. Eso significa que el mismo hilo puede bloquear el mismo mutex dos veces y no se estancará. Por supuesto, también necesita desbloquearlo dos veces, de lo contrario, ningún otro hilo puede obtener el mutex. No todos los sistemas que admiten pthreads también admiten mutex recursivos, pero si quieren cumplir con POSIX, deben hacerlo .
Otras API (más API de alto nivel) también suelen ofrecer mutexes, a menudo llamados bloqueos. Algunos sistemas / lenguajes (por ejemplo, Cocoa Objective-C) ofrecen mutexes recursivos y no recursivos. Algunos idiomas también solo ofrecen uno u otro. Por ejemplo, en Java los mutexes siempre son recursivos (el mismo hilo puede "sincronizarse" dos veces en el mismo objeto). Dependiendo de qué otra funcionalidad de hilo que ofrezcan, no tener mutex recursivos podría no ser un problema, ya que pueden escribirse fácilmente usted mismo (ya implementé mutex recursivos yo mismo sobre la base de operaciones mutex / condición más simples).
Lo que realmente no entiendo: ¿para qué sirven los mutexes no recursivos? ¿Por qué querría tener un punto muerto de hilo si bloquea el mismo mutex dos veces? Incluso los lenguajes de alto nivel que podrían evitar eso (por ejemplo, probar si esto se estancará y lanzar una excepción si lo hace) generalmente no lo hacen. Dejarán que el hilo se interrumpa.
¿Es esto solo para casos en los que accidentalmente lo bloqueo dos veces y solo lo desbloqueo una vez y en caso de un mutex recursivo, sería más difícil encontrar el problema, por lo que en su lugar tengo un punto muerto inmediato para ver dónde aparece el bloqueo incorrecto? Pero, ¿no podría hacer lo mismo con un contador de bloqueo devuelto al desbloquear y en una situación en la que estoy seguro de que liberé el último bloqueo y el contador no es cero, puedo lanzar una excepción o registrar el problema? ¿O hay algún otro caso de uso más útil de mutexes no recursivos que no veo? ¿O tal vez sea solo rendimiento, ya que un mutex no recursivo puede ser un poco más rápido que uno recursivo? Sin embargo, probé esto y la diferencia realmente no es tan grande.