POSIX permite que mutexes sejam recursivos. Isso significa que o mesmo encadeamento pode bloquear o mesmo mutex duas vezes e não entra em conflito. Obviamente, ele também precisa desbloqueá-lo duas vezes, caso contrário, nenhum outro thread pode obter o mutex. Nem todos os sistemas que suportam pthreads também suportam mutexes recursivos, mas se eles desejam estar em conformidade com POSIX, eles precisam .
Outras APIs (APIs de mais alto nível) também costumam oferecer mutexes, geralmente chamadas de bloqueios. Alguns sistemas / idiomas (por exemplo, Cocoa Objective-C) oferecem mutexes recursivos e não recursivos. Alguns idiomas também oferecem apenas um ou outro. Por exemplo, em Java, os mutexes são sempre recursivos (o mesmo thread pode "sincronizar" duas vezes no mesmo objeto). Dependendo de outras funcionalidades de encadeamento que eles oferecem, não ter mutexes recursivos pode não ser um problema, pois eles podem ser escritos facilmente (eu já implementei os mutexes recursivos com base em operações mais simples de mutex / condição).
O que realmente não entendo: Para que servem os mutexes não recursivos? Por que eu gostaria de ter um bloqueio de thread se ele bloqueia o mesmo mutex duas vezes? Mesmo linguagens de alto nível que poderiam evitar isso (por exemplo, testar se isso causará um impasse e lançar uma exceção, se houver) geralmente não fazem isso. Em vez disso, eles deixarão o bloqueio do encadeamento.
Isso é apenas para casos em que eu bloqueio acidentalmente duas vezes e desbloqueio apenas uma vez e no caso de um mutex recursivo, seria mais difícil encontrar o problema; portanto, tenho um bloqueio imediatamente para ver onde aparece o bloqueio incorreto? Mas não consegui fazer o mesmo com a devolução de um contador de bloqueio ao desbloquear e em uma situação, onde tenho certeza de que soltei o último bloqueio e o contador não é zero, posso lançar uma exceção ou registrar o problema? Ou há outro caso de uso mais útil de mutexes não recursivos que eu falho em ver? Ou talvez seja apenas desempenho, pois um mutex não recursivo pode ser um pouco mais rápido que um recursivo? No entanto, testei isso e a diferença não é tão grande assim.