Réponses:
Lorsque vous utilisez des verrous normaux (mutex, sections critiques, etc.), le système d'exploitation met votre thread dans l'état WAIT et le préempte en planifiant d'autres threads sur le même noyau. Cela a une pénalité de performances si le temps d'attente est vraiment court, car votre thread doit maintenant attendre une préemption pour recevoir à nouveau le temps CPU.
En outre, les objets du noyau ne sont pas disponibles dans tous les états du noyau, comme dans un gestionnaire d'interruption ou lorsque la pagination n'est pas disponible, etc.
Les Spinlocks ne provoquent pas de préemption mais attendent en boucle ("spin") jusqu'à ce que l'autre noyau libère le verrou. Cela empêche le thread de perdre son quantum et continue dès que le verrou est libéré. Le mécanisme simple des verrous rotatifs permet à un noyau de l'utiliser dans presque tous les états.
C'est pourquoi sur une machine à un seul cœur, un verrou tournant est simplement un "désactiver les interruptions" ou "augmenter l'IRQL" qui empêche complètement la planification des threads.
Les Spinlocks permettent en fin de compte aux noyaux d'éviter les «Big Kernel Lock» (un verrou acquis lorsque le noyau entre dans le noyau et libéré à la sortie) et ont un verrouillage granulaire sur les primitives du noyau, entraînant un meilleur multi-traitement sur les machines multi-cœurs donc de meilleures performances.
EDIT : Une question s'est posée: "Cela signifie-t-il que je devrais utiliser des verrous rotatifs dans la mesure du possible?" et j'essaierai d'y répondre:
Comme je l'ai mentionné, les Spinlocks ne sont utiles que dans les endroits où le temps d'attente anticipé est plus court qu'un quantum (lire: millisecondes) et la préemption n'a pas beaucoup de sens (par exemple, les objets du noyau ne sont pas disponibles).
Si le temps d'attente est inconnu ou si vous êtes en mode utilisateur, les Spinlocks ne sont pas efficaces. Vous consommez 100% du temps CPU sur le cœur en attente tout en vérifiant si un verrou tournant est disponible. Vous empêchez d'autres threads de s'exécuter sur ce noyau jusqu'à ce que votre quantum expire. Ce scénario n'est réalisable que pour de courtes rafales au niveau du noyau et peu probable une option pour une application en mode utilisateur.
Voici une question sur SO abordant cela: Spinlocks, quelle est leur utilité?
Supposons qu'une ressource est protégée par un verrou, un thread qui souhaite accéder à la ressource doit d'abord acquérir le verrou. Si le verrou n'est pas disponible, le thread peut vérifier à plusieurs reprises si le verrou a été libéré. Pendant ce temps, le thread occupé attend, vérifiant le verrou, utilisant le processeur, mais ne faisant aucun travail utile. Un tel verrou est appelé verrou tournant.
C'est bien une boucle qui continue jusqu'à ce qu'une certaine condition soit remplie:
while(cantGoOn) {};
sleep(0)
cela devancerait le thread, tuant le but d'utiliser un verrou tournant en premier lieu. si vous avez besoin de céder à d'autres threads, vous devriez utiliser un verrou normal. (Je sais que votre commentaire est très ancien mais je voulais empêcher les autres de voir cela comme une suggestion).
while(something != TRUE ){};
// it happend
move_on();
C'est un type de serrure qui attend beaucoup
Il est considéré comme un anti-pattern, sauf pour la programmation de pilotes de très bas niveau (où il peut arriver que l'appel d'une fonction d'attente "correcte" ait plus de surcharge que le simple verrouillage occupé pendant quelques cycles).
Voir par exemple Spinlocks dans le noyau Linux .
Les SpinLocks sont ceux dans lesquels le thread attend jusqu'à ce que le verrou soit disponible. Ceci sera normalement utilisé pour éviter la surcharge liée à l'obtention des objets du noyau lorsqu'il y a une possibilité d'acquérir l'objet du noyau dans un court laps de temps.
Ex:
While(SpinCount-- && Kernel Object is not free)
{}
try acquiring Kernel object
Vous voudrez utiliser un verrou tournant lorsque vous pensez qu'il est moins coûteux d'entrer dans une boucle d'attente occupée et de regrouper une ressource au lieu de la bloquer lorsque la ressource est verrouillée.
La rotation peut être bénéfique lorsque les verrous sont à grain fin et en grand nombre (par exemple, un verrou par nœud dans une liste liée) ainsi que lorsque les temps de maintien des verrous sont toujours extrêmement courts. En général, tout en maintenant un verrou tournant, il faut éviter de bloquer, appeler tout ce qui peut lui-même bloquer, maintenir plus d'un verrou tournant à la fois, faire des appels distribués dynamiquement (interface et virtuels), faire des appels distribués statiquement dans n'importe quel code que l'on ne fait pas. t posséder ou allouer de la mémoire.
Il est également important de noter que SpinLock est un type valeur, pour des raisons de performances. En tant que tel, il faut être très prudent de ne pas copier accidentellement une instance SpinLock, car les deux instances (l'original et la copie) seraient alors complètement indépendantes l'une de l'autre, ce qui entraînerait probablement un comportement erroné de l'application. Si une instance SpinLock doit être transmise, elle doit être transmise par référence plutôt que par valeur.
En bref, spinlock utilise des instructions de comparaison et d'échange atomiques (CAS) ou des instructions de type test-and-set pour implémenter un idiome sans verrouillage et sans attente. De telles structures évoluent bien dans les machines multicœurs.
Eh bien, oui - le point des verrous de rotation (par rapport aux sections critiques traditionnelles, etc.) est qu'ils offrent de meilleures performances dans certaines circonstances (systèmes multicœurs ...), car ils ne donnent pas immédiatement le reste du quantum du thread.
Spinlock, est un type de verrou, qui ne peut pas bloquer et ne peut pas dormir. Tout thread qui souhaite acquérir un verrou tournant pour une ressource partagée ou critique tournera continuellement, gaspillant le cycle de traitement du processeur jusqu'à ce qu'il acquière le verrou pour la ressource spécifiée. Une fois le verrou tournant acquis, il essaie de terminer le travail dans son quantum puis de libérer la ressource respectivement. Spinlock est le type de verrou le plus prioritaire, on peut simplement dire qu'il s'agit d'un type de verrou non préemptif.