Je comprends que mutex récursif permet à mutex d'être verrouillé plus d'une fois sans aboutir à une impasse et doit être déverrouillé le même nombre de fois. Mais dans quelles situations spécifiques avez-vous besoin d'utiliser un mutex récursif? Je recherche des situations au niveau de la conception / du code.
Réponses
Trop de publicités?Par exemple, lorsque vous avez une fonction qui l’appelle de manière récursive et que vous souhaitez obtenir un accès synchronisé à celle-ci:
void foo() {
... mutex_acquire();
... foo();
... mutex_release();
}
sans mutex récursif, vous devez d'abord créer une fonction "point d'entrée", ce qui devient fastidieux lorsque vous disposez d'un ensemble de fonctions mutuellement récursives. Sans mutex récursif:
void foo_entry() {
mutex_acquire(); foo(); mutex_release(); }
void foo() { ... foo(); ... }
Récursifs et non récursifs mutex ont différents cas d'utilisation. Pas de mutex type peuvent facilement remplacer les autres. Non-récursive mutex ont moins de frais généraux, et de récursive mutex ont, dans certaines situations, utiles ou même nécessaires, de la sémantique et dans d'autres situations dangereuses ou même cassés de la sémantique. Dans la plupart des cas, quelqu'un peut remplacer n'importe quelle stratégie récursive à l'aide de mutex avec un autre plus sûr et plus efficace de la stratégie basée sur l'utilisation de la non-récursive mutex.
- Si vous voulez juste pour exclure les autres threads à l'aide de votre mutex ressource protégée, alors vous pourriez utiliser tout mutex type, mais peut vouloir utiliser le non-récursive mutex en raison de la petitesse de ses frais généraux.
- Si vous souhaitez appeler des fonctions récursives, qui bloquent la même mutex, puis ils
- utiliser un récursif mutex, ou
- ont pour déverrouiller et verrouiller le même non-récursive mutex encore et encore (méfiez-vous de threads simultanés!), ou
- ont en quelque sorte annoter qui mutex ils déjà verrouillé (simulation récursive propriété/mutex).
- Si vous souhaitez verrouiller plusieurs mutex-objets protégés à partir d'un ensemble de tels objets, où les décors auraient pu être construits par la fusion, vous pouvez choisir
- à utiliser par objet exactement un mutex, permettant à plus de threads de travail en parallèle, ou
- à utiliser pour objet une référence pour tout probablement partagées récursive mutex, afin de réduire la probabilité d'échec pour verrouiller tous les mutex ensemble, ou
- à utiliser pour objet un comparable de référence pour tout éventuellement partagée non-récursive de mutex, de contourner l'intention de verrouiller plusieurs fois.
- Si vous souhaitez mettre un verrou dans un thread différent qu'il a été verrouillé, alors vous devez utiliser non-récursive de serrures (ou récursive écluses qui permettent explicitement ce au lieu de lancer des exceptions).
- Si vous souhaitez utiliser la synchronisation des variables, alors vous devez être en mesure explicitement déverrouille le mutex, lors de l'attente sur toute synchronisation variable, de sorte que la ressource est autorisé à être utilisé dans d'autres threads. C'est seulement sainement possible avec des non-récursive de mutex, parce que récursive mutex pourrait déjà avoir été verrouillé par l'appelant de la fonction en cours.
Si vous souhaitez voir un exemple de code utilisant des mutex récursifs, consultez les sources de "Electric Fence". C'est l'un des outils Unix courants pour la "vérification des limites" avant l'arrivée de Valgrind.
Compilez-le et associez-le à votre programme avec les sources, et commencez à le parcourir.