Qu'est-ce que Verrou tournant (spinlock) ?

Verrou dont l'attente consiste à tester en boucle la variable de verrou jusqu'à ce qu'il se libère. Rapide pour les attentes courtes, mais le CPU reste occupé pendant l'attente.

Nom japonais: スピンロック

« Verrou tournant (spinlock) » apparaît dans 4 questions d'entraînement réparties sur 1 thèmes, dont Multicœur et synchronisation.

Domaine: Multicœur et synchronisation

Comment un verrou tournant s'acquiert et se libère

Un verrou tournant est une variable partagée, valant généralement 0 lorsqu'il est libre et 1 lorsqu'il est pris. Pour l'acquérir, un thread utilise une instruction atomique de lecture-modification-écriture comme test-and-set, swap ou compare-and-swap, qui met la variable à 1 et renvoie l'ancienne valeur en une seule étape indivisible ; en RISC-V, il s'agit d'un swap atomique ou d'une paire load-reserved/store-conditional. Si l'ancienne valeur était 0, le thread possède le verrou ; sinon, il réessaie en boucle. La libération consiste simplement à écrire 0. L'acquisition et la libération doivent aussi agir comme des barrières mémoire, afin que les accès de la section critique restent entre les deux.

Test-and-test-and-set et trafic de cache

Réessayer l'instruction atomique dans une boucle serrée donne de mauvaises performances sur les puces multicœurs. Chaque opération atomique exige la propriété exclusive de la ligne de cache ; les cœurs en attente ne cessent donc de ramener la ligne à l'état modifié (M) et d'invalider les copies des autres, inondant l'interconnexion de cohérence. Le motif test-and-test-and-set attend plutôt avec des chargements ordinaires : chaque thread en attente lit sa propre copie partagée dans son cache, sans générer de trafic, et ne tente l'opération atomique que lorsqu'il voit le verrou se libérer. Le recul exponentiel (backoff) et les verrous à ticket ou à file réduisent encore la contention et ajoutent de l'équité.

Verrou tournant ou mutex

Un mutex qui endort place le thread en attente dans un état bloqué et cède le CPU à d'autres threads ; le système d'exploitation le réveille à la libération du verrou. Cela ne gaspille aucun temps CPU, mais coûte un appel système, un ordonnancement et un changement de contexte, généralement plusieurs microsecondes. Un verrou tournant évite entièrement ce surcoût et l'emporte lorsque le verrou n'est détenu que brièvement, moins longtemps que ne prendrait un cycle d'endormissement et de réveil. Pour les durées de détention longues, l'équilibre s'inverse ; de nombreux mutex de bibliothèque tournent donc d'abord brièvement puis s'endorment, combinant les avantages des deux.

Où les verrous tournants conviennent et où ils échouent

Les verrous tournants sont courants dans les noyaux de systèmes d'exploitation, pour les sections critiques courtes sur multiprocesseurs et pour les données partagées avec les gestionnaires d'interruption, qui ne peuvent pas dormir. Le code qui détient un verrou tournant ne doit pas dormir, et les noyaux désactivent généralement la préemption, ainsi que les interruptions si nécessaire, pendant sa détention, afin qu'un gestionnaire d'interruption sur le même cœur ne tourne pas indéfiniment sur un verrou détenu par son propre cœur. Sur un système monocœur, un verrou tournant en espace utilisateur est particulièrement coûteux : le détenteur ne peut pas s'exécuter pour libérer le verrou pendant que l'autre thread tourne, si bien que ce dernier consomme toute sa tranche de temps.

S'entraîner : questions sur Verrou tournant (spinlock)

Quelle description du verrou à attente active (spinlock) est correcte ?

  1. AVerrou qui endort le thread jusqu’à la libération et le fait réveiller par l’OS
  2. BVerrou qui attend la libération en examinant en boucle la variable de verrou
  3. CMécanisme qui protège les données en faisant tourner un disque
Afficher la réponse et l'explication

Réponse : B. Verrou qui attend la libération en examinant en boucle la variable de verrou

Le spinlock tente de prendre le verrou avec une instruction atomique et, en cas d’échec, réessaie immédiatement, de façon répétée. Sans le coût d’appeler l’OS pour s’endormir puis se réveiller, il est rapide lorsque le verrou n’est détenu que très brièvement. Il est très utilisé dans le noyau de l’OS et pour l’exclusion mutuelle avec les gestionnaires d’interruption. En revanche, il a l’inconvénient de continuer à consommer du CPU pendant l’attente.

Dans quelle situation le spinlock est-il le moins adapté ?

  1. ALorsque le verrou est détenu longtemps et que les threads en attente gaspillent du CPU
  2. BLorsque le verrou n’est détenu que quelques dizaines de nanosecondes
  3. CDans un traitement du noyau de l’OS qui ne peut pas s’endormir
Afficher la réponse et l'explication

Réponse : A. Lorsque le verrou est détenu longtemps et que les threads en attente gaspillent du CPU

Un thread qui attend un spinlock continue d’utiliser le CPU jusqu’à la libération. Si le verrou est détenu longtemps, tout ce temps CPU est gaspillé et gêne l’exécution des autres threads. En particulier, avec un seul cœur, le verrou ne se libère que si le thread détenteur s’exécute ; l’attente dure donc jusqu’à la fin du quantum de temps. Pour les attentes longues, on utilise un mutex qui attend en dormant ; il existe aussi des méthodes qui tournent brièvement avant de s’endormir.

Questions fréquentes

Quelle est la différence entre un verrou tournant et un mutex ?

Un verrou tournant attend en bouclant sur la variable de verrou et garde le CPU occupé, ce qui n'est efficace que pour des attentes très courtes. Un mutex endort le thread en attente et laisse d'autres threads s'exécuter, ce qui convient aux attentes plus longues mais ajoute le coût de l'endormissement, du réveil et du changement de contexte.

Quand faut-il utiliser un verrou tournant ?

Utilisez-en un lorsque la section critique est très courte et que les threads s'exécutent sur des cœurs différents, ou dans des contextes noyau comme les gestionnaires d'interruption, qui n'ont pas le droit de dormir. Évitez-le lorsque le verrou peut être détenu longtemps ou sur les systèmes monocœurs.

Qu'est-ce que le test-and-test-and-set ?

C'est une technique de verrou tournant dans laquelle les threads en attente lisent en boucle le verrou par des chargements ordinaires depuis leur propre cache et ne tentent le test-and-set atomique que lorsque le verrou semble libre. Cela évite les invalidations continuelles de lignes de cache et réduit fortement le trafic de cohérence.

« Verrou tournant (spinlock) » dans les explications

Questions mentionnant « Verrou tournant (spinlock) » (4)

  1. Quelle description du verrou à attente active (spinlock) est correcte ?
  2. Dans quelle situation le spinlock est-il le moins adapté ?
  3. Dans un spinlock, pourquoi attendre la libération par des lectures ordinaires et n’utiliser l’instruction atomique que lorsque le verrou semble libre (test-and-test-and-set), plutôt que de tenter directement la modification par instruction atomique ?
  4. Quelle comparaison entre mutex (verrou à attente en sommeil) et spinlock est correcte ?

Comparatifs incluant ce terme

Termes associés

Instruction atomique Mutex Interruption Temps CPU Changement de contexte Acquisition-libération (acquire-release) Barrière mémoire Cohérence séquentielle Compare-and-swap Course aux données (data race)

Retour au glossaire