Re-participant de verrouillage
Réentrante de verrouillage est celui où un processus peut demander le verrouillage à plusieurs reprises sans blocage sur lui-même. Il est utile dans les situations où il n'est pas facile de garder une trace de savoir si vous avez déjà attrapé une serrure. Si un verrou est non réentrant vous pourriez saisir le verrou, puis bloquer quand vous allez à la saisir à nouveau, de manière efficace de blocage de votre propre processus.
La réentrance, en général, est une propriété de code où il n'a pas de centrale mutable état qui pourraient être endommagés si le code a été appelé alors qu'il est en cours d'exécution. Un tel appel peut être effectué par un autre thread, ou il peut être fait de manière récursive par un chemin d'exécution en provenance de l'intérieur le code lui-même.
Si le code s'appuie sur l'état partagé qui pourrait être mis à jour dans le milieu de son exécution, il n'est pas réentrant, du moins pas si cette mise à jour pourrait le casser.
Un cas d'utilisation pour ré-entrant de verrouillage
Un (un peu générique et artificiel) exemple d'une demande de ré-entrant de verrouillage peut être:
Vous avez quelques calculs impliquant un algorithme qui parcourt un graphique (peut-être avec des cycles). Un parcours peut visiter le même nœud plus d'une fois en raison de l'cycles ou en raison de plusieurs chemins vers le même nœud.
La structure des données est soumise à l'accès simultané et pourrait être mis à jour pour une raison quelconque, peut-être par un autre thread. Vous devez être en mesure de verrouiller les nœuds individuels pour parer au risque de corruption des données en raison de conditions de course. Pour une raison quelconque (peut-être la performance) vous ne voulez pas globalement de verrouillage de l'ensemble de la structure de données.
Vous calcul ne peut pas conserver les informations complètes sur ce que les nœuds que vous avez visité, ou que vous soyez à l'aide d'une structure de données qui ne permet pas " ai-je été ici avant de questions à réponse rapidement.
Un exemple de cette situation pourrait être une simple mise en œuvre de l'algorithme de Dijkstra avec une file d'attente de priorité de mise en œuvre comme un tas binaire ou en largeur d'abord chercher à l'aide d'une simple liste chaînée comme une file d'attente. Dans ces cas, la numérisation de la file d'attente pour les insertions est de O(N) et vous ne voulez pas le faire à chaque itération.
Dans cette situation, garder une trace de ce que les verrous que vous avez déjà acquise est cher. En supposant que vous voulez faire de verrouillage au niveau du nœud d'une ré-entrant mécanisme de verrouillage atténue le besoin de dire si vous avez déjà visité un nœud avant. Vous pouvez simplement aveuglément verrouiller le nœud, peut-être déverrouillage une fois que vous pop hors de la file d'attente.
Ré-entrant mutex
Un simple mutex n'est pas réentrant comme un seul thread peut être dans la section critique à un moment donné. Si vous prenez le mutex et puis essayer de la saisir de nouveau un simple mutex ne pas avoir assez d'informations pour dire qui tenait auparavant. Pour ce faire, récursivement, vous avez besoin d'un mécanisme où chaque thread a un jeton de sorte que vous pourriez dire qui avait saisi le mutex. Cela rend le mécanisme de mutex un peu plus cher, donc vous ne voulez pas le faire dans toutes les situations.
IIRC les threads POSIX API ne vous offrons la possibilité de ré-entrant et non réentrant mutex.