Spinlock et sémaphore diffèrent principalement dans quatre choses:
1. Ce qu'ils sont
Un spinlock est une implémentation possible de la serrure, à savoir celui qui est mis en œuvre par occupé attente ("spinning"). Un sémaphore est une généralisation d'un verrou (ou, à l'inverse, un verrou est un cas particulier d'un sémaphore). Généralement, mais pas nécessairement, spinlocks ne sont valables que dans un seul processus, alors que les sémaphores peuvent être utilisés pour la synchronisation entre les différents processus, trop.
Une serrure fonctionne pour l'exclusion mutuelle, c'est-à un thread à la fois peut acquérir le verrou et de procéder à une "section critique" de code. Habituellement, cela signifie que le code qui modifie certaines données partagées par plusieurs threads.
Un sémaphore a un compteur et permettra même d'être acquis par un ou plusieurs fils, selon la valeur que vous publiez, et (dans certaines implémentations) en fonction de ce que sa valeur maximale admissible est.
Pour autant, la possibilité de verrouiller un cas particulier d'un sémaphore avec une valeur maximale de 1.
2. Ce qu'ils ne
Comme indiqué ci-dessus, un spinlock est un verrou, et, par conséquent, une exclusion mutuelle (strictement 1 à 1) mécanisme. Il travaille à plusieurs reprises par l'interrogation et/ou de la modification d'un emplacement de mémoire, généralement dans une manière atomique. Cela signifie que l'acquisition d'un spinlock est "occupé" fonctionnement que, éventuellement, les brûlures de cycles CPU pour un long moment (peut-être pour toujours!) alors qu'il atteint efficacement "rien".
La principale motivation d'une telle approche est le fait qu'un changement de contexte a une charge équivalente à la filature de quelques centaines (ou milliers) de fois, donc si un verrou peut être acquis par la gravure d'un certain nombre de cycles de tourner, ce qui peut dans l'ensemble très bien être plus efficace. Aussi, pour des applications temps-réel, il peut ne pas être acceptable pour bloquer et d'attendre que le planificateur de revenir au loin dans l'avenir.
Un sémaphore, en revanche, ne fait pas tourner du tout, ou seulement tourne pendant un temps très court (comme une optimisation pour éviter le syscall généraux). Si un sémaphore ne peut pas être acquis, il bloque, en donnant de temps PROCESSEUR à un autre thread qui est prêt à s'exécuter. Cela peut évidemment dire que quelques millisecondes avant de passer votre fil est prévu à nouveau, mais si ce n'est pas un problème (en général, il n'est pas), alors il peut être très efficace, L'approche conservatrice.
3. Comment ils se comportent en présence de congestion
C'est une idée fausse commune que les spinlocks ou sans verrouillage des algorithmes sont "généralement plus rapide", ou qu'ils ne sont utiles que pour les "très court tâches" (idéalement, un objet de synchronisation doivent être conservées plus longtemps que nécessaire, jamais).
La seule différence importante est de savoir comment les différentes approches comportent en présence de congestion.
Un système bien conçu a normalement peu ou pas de congestion (ce qui ne signifie pas tous les threads tentent d'acquérir le verrou à l'exact même temps). Par exemple, on pourrait normalement pas écrire du code qui acquiert un verrou, puis charge la moitié d'un mégaoctet de zip compressé des données à partir du réseau, décode et analyse les données, et enfin modifie une référence partagée (ajout de données à un conteneur, etc.) avant de relâcher le verrou. Au lieu de cela, on pourrait acquérir le verrou dans le seul but d'accéder à la ressource partagée.
Car cela signifie qu'il existe beaucoup plus de travail à l'extérieur de la section critique qu'à l'intérieur d'elle, naturellement, la probabilité pour un thread qui est à l'intérieur de la section critique est relativement faible, et donc quelques fils sont à la lutte pour le verrouiller en même temps. Bien sûr, chaque maintenant et puis les deux fils va essayer d'acquérir le verrou dans le même temps (si ce ne pouvais pas vous arrive, vous n'auriez pas besoin d'une serrure!), mais c'est l'exception plutôt que la règle dans une "bonne santé" du système.
Dans un tel cas, un spinlock grandement surpasse un sémaphore parce que si il n'y a pas de verrouillage de la congestion, les frais généraux de l'acquisition de la spinlock est une simple dizaine de cycles par rapport à des centaines/milliers de cycles pour un changement de contexte ou de 10 à 20 millions de cycles pour perdre le reste de la tranche de temps.
D'autre part, étant donné le niveau élevé d'encombrement, ou si le verrou est détenu pendant de longues périodes (parfois vous ne pouvez pas l'aider!), spinlock brûlera fou quantités de cycles CPU pour parvenir à rien.
Un sémaphore (ou mutex) est un bien meilleur choix dans ce cas, car elle permet à un thread différent pour exécuter utile tâches pendant ce temps. Ou, si aucun autre thread a quelque chose d'utile, il permet au système d'exploitation de ralentir le CPU et réduire la chaleur /économiser de l'énergie.
Aussi, sur un single-core, un système de spinlock sera tout à fait inefficace en présence de verrouillage de la congestion, comme un coup de fil de déchets de son temps à attendre un changement d'état qui ne peut pas arriver (pas jusqu'à la libération thread est prévue, qui n'est pas le cas tandis que le thread en attente en cours d'exécution!). Par conséquent, compte tenu de tout montant de contention, de l'acquisition du verrou prend environ 1 1/2 tranches de temps dans le meilleur des cas (en supposant que la libération fil conducteur est le suivant étant prévu), ce qui n'est pas un très bon comportement.
4. La façon dont ils sont mis en œuvre
Un sémaphore sera aujourd'hui enveloppez sys_futex sous Linux (éventuellement avec un spinlock qui se ferme après quelques tentatives).
Spinlock est généralement mis en œuvre à l'aide d'opérations atomiques, et sans l'aide de rien fourni par le système d'exploitation. Dans le passé, cela signifie en utilisant soit le compilateur intrinsèques ou non-portable instructions en assembleur. Pendant ce temps les deux C++11 et C11 ont des opérations atomiques dans le cadre de la langue, donc, en dehors de la difficulté générale de l'écriture prouvable de verrouillage correct sans code, il est maintenant possible de mettre en œuvre sans verrouillage de code dans un lieu entièrement portable et (presque) sans douleur façon.
“Aussi, sur un single-core, un système de spinlock sera tout à fait inefficace en présence de verrouillage de la congestion, comme un coup de fil de déchets de son temps à attendre un changement d'état qui ne peut absolument pas se produire” : il y a aussi (au moins sous Linux) le spin_trylock, qui renvoie immédiatement avec un code d'erreur, si le verrou n'a pas pu être acquis. Un spin‑lock n'est pas toujours aussi sévère. Mais à l'aide de spin_trylock nécessite, pour une application, pour être bien conçu (probablement une file d'attente des opérations en attente, et ici, de choisir le prochain, laissant le réel dans la file d'attente).
Le blocage de mutex et les sémaphores ne sont pas seulement utiles dans un seul thread environnements mais également s'il y a surcharge, c'est le nombre de threads d'un programme (ou de plusieurs programmes de partage du système) crée est plus élevé que le nombre de ressources matérielles. Dans ces cas, le blocage de votre fil permet aux autres d'être en mesure d'utiliser le temps CPU de manière utile. En outre, si le matériel supporte l'hyperthreading, l'autre thread peut utiliser les unités d'exécution qui sont utilisés pour effectuer la boucle d'inactivité.
très simplement, un sémaphore est un "rendement" de la synchronisation de l'objet, spinlock est un "busywait' un. (il y a un peu plus de sémaphores en ce qu'elles synchroniser plusieurs threads, contrairement à un mutex ou de la garde ou à un moniteur ou une section critique qui protège une région de code à partir d'un seul thread)
Vous souhaitez utiliser un sémaphore dans plusieurs circonstances, mais l'utilisation d'un spinlock où vous allez à verrouiller pour un très court laps de temps - il y a un coût pour le verrouillage surtout si vous verrouillez beaucoup. Dans de tels cas, il peut être plus efficace de spinlock pour un peu de temps d'attente pour la ressource protégée pour devenir déverrouillé. Évidemment, il y a un gain de performance si vous tournez trop longtemps.
en règle générale, si vous faites tourner pendant plus d'un fil quantique, alors vous devriez utiliser un sémaphore.
Au-delà de ce Yoav Aviram et gbjbaanb dit, l'autre point clé est utilisé pour être que vous n'auriez jamais utiliser un spin-lock sur une machine mono-PROCESSEUR, alors qu'un sémaphore aurait du sens sur une telle machine. Aujourd'hui, vous êtes souvent du mal à trouver une machine sans noyaux multiples, ou de l'hyperthreading, ou l'équivalent, mais dans les circonstances que vous avez juste un seul PROCESSEUR, vous devez utiliser les sémaphores. (J'ai confiance en la raison en est évidente. Si le CPU est occupé attente de quelque chose d'autre pour libérer le spin-lock, mais il est en cours d'exécution sur le seul CPU, la serrure est peu probable d'être libéré jusqu'à ce que le processus ou thread est interrompu par l'O/S, ce qui peut prendre un certain temps et que rien d'utile ne se passe jusqu'à ce que le droit de préemption se produit.)
J'aimerais deuxième combien il est important de ne pas utiliser les spinlocks sur mono-thread systèmes. Ils sont le fait tic-tac pour inversion de priorité des problèmes. Et croyez-moi: Vous ne voulez pas de débogage de ce genre de bugs.
spinlocks sont partout dans le noyau Linux, peu importe si vous avez un ou plusieurs Processeurs. Que voulez-vous dire exactement?
par définition, un spinlock signifie que le thread en cours sur le CPU est en attente de quelque chose d'autre pour libérer l'objet verrouillé. Si le seul truc qui peut changer la serrure est le CPU actuel, la serrure ne sera pas libéré par la filature. Si quelque chose d'autre, un transfert DMA ou d'autres I/O contrôleur peut libérer le verrou, tout va bien. Mais tourne quand rien d'autre ne peut libérer le verrou n'est pas très raisonnable, vous pourriez aussi bien le rendement du PROCESSEUR à un autre processus maintenant que d'attendre d'être préempté.
Je peut très bien être faux, mais j'étais sous l'impression qu'une ré-entrant (UC) du noyau Linux peut interrompre l'exécution d'un verrou de rotation.
il y a une chance que je me trompe aussi, mais je pense que je suis proche de la définition classique d'un spinlock. Avec maintien du droit préférentiel de planification, un processus peut tourner sur un verrou jusqu'à la fin de sa tranche de temps, ou jusqu'à ce qu'une interruption à cause de la liberté, mais si un autre processus doit fournir la condition qui permet à l'spin lock pour verrouiller, spinlock est pas une bonne idée sur un seul PROCESSEUR de la machine. Le système que je travail sur a spinlocks et a un configurable limite supérieure sur le nombre de tours avant qu'il aille dans une situation de non-occupée mode attente. C'est un niveau de l'utilisateur spin-lock; il peut y avoir une différence dans le noyau.
Désolé, je downvoted votre réponse - alors que les spinlocks peut souvent ne pas être une bonne idée de la performance sage, presque tout système moderne je connais (que ce soit mono ou multi-CPU, serveur ou intégrés) utilise une sorte de non-multitâche coopératif, où le blocage de la tâche n'a pas à céder manuellement. Ainsi, un énoncé général qui spinlocks ne peut pas être utilisé sur un seul Cpu est tout simplement faux.
Où puis-je dire "spinlock ne peut pas être utilisé sur un seul Cpu"? - Je vous dire "vous n'auriez jamais utiliser un spin-lock sur une machine mono-PROCESSEUR" (à noter que "serait" est très différent de "pouvoir"!) et de décrire ce qui se passe si vous n' ("si le CPU est occupé attente de quelque chose d'autre pour libérer le spin-lock, mais il est en cours d'exécution sur le seul CPU, la serrure est peu probable d'être libéré"). Je devrais peut-être ajouter "jusqu'à ce que le processus actuel ou le fil est devancé" -- mais le point principal reste: si vous utilisez un spinlock sur un seul PROCESSEUR de la machine, le processus peut tourner sur la serrure pour un long moment.
Vous écrivez "mais dans les circonstances que vous avez juste un seul PROCESSEUR, vous DEVEZ utiliser les sémaphores." Si vous supprimez le doit et ajouter la note que vous avez suggéré, je serais heureux de supprimer mon downvote. Aussi je ne suis pas sûr que cela encore quallifies comme un spinlock, mais j'ai vu des implémentations d'appel de rendement avant ils essaient d'acquérir de nouveau le verrou. Je suis complètement d'accord qu'il n'est généralement pas une bonne idée.
J'ai révisé la réponse à couvrir les points que nous avons abordés, qui sont également largement abordé dans le commentaire de l'année dernière.
Je ne suis pas un noyau d'experts, mais voici quelques points:
Même machine monoprocesseur pouvez utiliser le spin-serrures si le noyau de préemption est activé lors de la compilation du noyau. Si le noyau de préemption est désactivé alors spin-lock (peut-être) se développe à une vide déclaration.
Aussi, lorsque nous essayons de comparer Sémaphore vs Spin-lock, je crois sémaphore se réfère à celui utilisé dans le noyau et non PAS celui utilisé pour la CIB (userland).
Fondamentalement, le spin-lock doit être utilisé si la section critique est petite (plus petite que la surcharge du sommeil et de réveil) et de la section critique ne fait pas appel à tout ce qui peut dormir! Un sémaphore doit être utilisé si la section critique est plus grand et il peut dormir.
Spinlock se réfère à une mise en œuvre de l'inter-thread de verrouillage à l'aide dépend de la machine des instructions de montage (comme test-and-set). Il est appelé un spinlock parce que le thread attend tout simplement dans une boucle ("spins") la vérification à plusieurs reprises jusqu'à ce que le verrou est mis à disposition (attente active). Spinlocks sont utilisées comme un substitut pour les mutex, qui sont une installation fournies par les systèmes d'exploitation (et non le CPU), parce que les spinlocks fonctionne mieux si elle est verrouillée pour une courte période de temps.
Un Semaphor est un service fourni par les systèmes d'exploitation pour l'IPC, à cet effet, son but principal est inter-processus-de la communication. Étant une installation fournies par le système d'exploitation c'est la performance ne sera pas aussi bonne que celle d'un spinlock pour l'inter-thead verrouillage (bien que possible). Les sémaphores sont mieux pour le verrouillage pendant de longues périodes de temps.
Que dit - mise en œuvre de splinlocks dans le montage est délicat, et pas portable.
Tous les multi-threading Processeurs besoin d'un spinlock instruction ("test et ensemble") et il est toujours mis en œuvre comme une seule instruction dans le matériel, car il y aurait toujours être une condition de concurrence dans laquelle plus d'un fil de la pensée, il la "propriété" de la ressource protégée.
Je voudrais ajouter mes observations, plus général et pas très spécifique à Linux.
En fonction de l'architecture de la mémoire et de la capacité du processeur, vous pourriez avoir besoin d'un spin-lock afin de mettre en œuvre un sémaphore sur un multi-core ou un système multiprocesseur, car dans de tels systèmes, une race condition peut se produire lorsque deux ou plusieurs threads/processus souhaitez acquérir un sémaphore.
Oui, si votre architecture de la mémoire propose le verrouillage d'une section de mémoire par un core/processeur retarder tous les autres accès, et si votre processeurs propose un test-and-set, vous pouvez mettre en œuvre un sémaphore sans un spin-lock (mais très bien!).
Cependant, en tant que simple/à bas prix multi-core systèmes sont conçus (je travaille dans les systèmes embarqués), toutes les architectures de mémoire de soutien tels multi-core/multiprocesseur caractéristiques, seul test-and-set ou l'équivalent. Puis une mise en œuvre pourrait être comme suit:
acquérir le spin-lock (occupé attente)
essayer d'acquérir le sémaphore
libérer le spin-lock
si le sémaphore n'a pas été acquis avec succès, de suspendre le thread courant jusqu'à ce que le sémaphore est libéré; sinon passez à la section critique
Libérer le sémaphore doit être mise en oeuvre comme suit:
acquérir le spin-lock
libérer le sémaphore
libérer le spin-lock
Oui, et pour de simples sémaphores binaires sur un niveau de l'OS, il serait possible de n'utiliser qu'un spin-lock de remplacement. Mais seulement si le code-sections afin d'être protégés sont vraiment très petits.
Comme dit avant, si et quand vous mettez en place votre propre système d'exploitation, assurez-vous d'être prudent. Débogage de telles erreurs, c'est fun (à mon avis, n'est pas partagée par beaucoup), mais surtout très pénible et difficile.
Un "mutex" (ou "verrou d'exclusion mutuelle") est un signal que deux ou plusieurs processus asynchrones peuvent utiliser pour réserver une ressource partagée pour une utilisation exclusive. Le premier processus qui obtient la propriété de la "mutex" obtient également la propriété de la ressource partagée. D'autres processus doit attendre pour le premier processus de libération, c'est la propriété de la "mutex" avant qu'ils peuvent essayer de l'obtenir.
Le plus commun de verrouillage primitive dans le noyau est le spinlock. Le spinlock est très simple, seul détenteur de la serrure. Si un processus tente d'acquérir un spinlock et il n'est pas disponible, le processus va continuer d'essayer (la filature) jusqu'à ce qu'il peut acquérir le verrou. Cette simplicité crée une petite et rapide de serrure.
Spinlock est utilisé si et seulement si vous êtes sûr que votre résultat attendu se produira très peu de temps, avant votre fil d'exécution de la tranche de temps expire.
Exemple: Dans le module de pilote de périphérique, Le pilote écrit "0" dans le matériel le Registre R0 et maintenant, il faut attendre que R0 inscrire pour devenir 1. Le H/W lit le R0 et fait un peu de travail et de l'écrit "1" dans R0. C'est généralement rapide(micro-secondes). Maintenant, la filature est beaucoup mieux que d'aller dormir et a été interrompu par la H/W. bien sûr, tandis que la filature, le H/W condition d'échec doit être pris en charge!
Il n'y a absolument aucune raison pour qu'un utilisateur de l'application pour tourner. Il ne fait pas de sens. Vous vous apprêtez à tourner pendant un certain événement se produise et que l'événement doit être complété par un autre utilisateur de niveau application qui n'est jamais garanti d'arriver dans rapide laps de temps. Donc, je ne tourne pas du tout en mode utilisateur. Je ferais mieux de dormir() ou mutexlock() ou sémaphore lock() en mode utilisateur.
À la fois la gestion d'une ressource limitée. Je vais d'abord décrire la différence entre le binaire sémaphore (mutex) et le verrou de rotation.
Verrous de rotation effectuer une attente active - c'est à dire qu'il continue de fonctionner en boucle:
while (try_acquire_resource ());
...
release();
Il effectue très léger, verrouillage/déverrouillage, mais si le verrouillage fil sera retardé par d'autres qui tentent d'accéder à la même ressource, la seconde va simplement essayer de acquitre de ressources jusqu'à ce qu'il exécuter de CPU quanta.
Ainsi, si le thread va essayer d'acquérir des ressources bloquées, il sera suspendu jusqu'à ce qu'il sera disponible pour elle. Verrouillage/déverrouillage est beaucoup plus lourd, mais l'attente est "libre" et "juste".
Sémaphore est une serrure qui est autorisé à être utilisé à plusieurs (connu à partir de l'initialisation) nombre de fois, par exemple, 3 fils sont autorisés à simultainusly tenir la ressource, mais pas plus. Il est utilisé par exemple dans producteur/consommateur problème ou en général dans les files d'attente:
P(resources_sem)
ressource = ressources.pop()
...
les ressources.push(ressources)
V(resources_sem)
verrou de rotation peut être occupé que par un seul processus, alors que le sémaphore peut être détenus par un ou plusieurs processus.
Verrou de rotation attendre jusqu'à ce que le processus libère un verrou, puis acquiert un verrou.
Sémaphore est en sommeil, je lock.e attend et va dormir.
Spinlock et sémaphore diffèrent principalement dans quatre choses:
1. Ce qu'ils sont
Un spinlock est une implémentation possible de la serrure, à savoir celui qui est mis en œuvre par occupé attente ("spinning"). Un sémaphore est une généralisation d'un verrou (ou, à l'inverse, un verrou est un cas particulier d'un sémaphore). Généralement, mais pas nécessairement, spinlocks ne sont valables que dans un seul processus, alors que les sémaphores peuvent être utilisés pour la synchronisation entre les différents processus, trop.
Une serrure fonctionne pour l'exclusion mutuelle, c'est-à un thread à la fois peut acquérir le verrou et de procéder à une "section critique" de code. Habituellement, cela signifie que le code qui modifie certaines données partagées par plusieurs threads.
Un sémaphore a un compteur et permettra même d'être acquis par un ou plusieurs fils, selon la valeur que vous publiez, et (dans certaines implémentations) en fonction de ce que sa valeur maximale admissible est.
Pour autant, la possibilité de verrouiller un cas particulier d'un sémaphore avec une valeur maximale de 1.
2. Ce qu'ils ne
Comme indiqué ci-dessus, un spinlock est un verrou, et, par conséquent, une exclusion mutuelle (strictement 1 à 1) mécanisme. Il travaille à plusieurs reprises par l'interrogation et/ou de la modification d'un emplacement de mémoire, généralement dans une manière atomique. Cela signifie que l'acquisition d'un spinlock est "occupé" fonctionnement que, éventuellement, les brûlures de cycles CPU pour un long moment (peut-être pour toujours!) alors qu'il atteint efficacement "rien".
La principale motivation d'une telle approche est le fait qu'un changement de contexte a une charge équivalente à la filature de quelques centaines (ou milliers) de fois, donc si un verrou peut être acquis par la gravure d'un certain nombre de cycles de tourner, ce qui peut dans l'ensemble très bien être plus efficace. Aussi, pour des applications temps-réel, il peut ne pas être acceptable pour bloquer et d'attendre que le planificateur de revenir au loin dans l'avenir.
Un sémaphore, en revanche, ne fait pas tourner du tout, ou seulement tourne pendant un temps très court (comme une optimisation pour éviter le syscall généraux). Si un sémaphore ne peut pas être acquis, il bloque, en donnant de temps PROCESSEUR à un autre thread qui est prêt à s'exécuter. Cela peut évidemment dire que quelques millisecondes avant de passer votre fil est prévu à nouveau, mais si ce n'est pas un problème (en général, il n'est pas), alors il peut être très efficace, L'approche conservatrice.
3. Comment ils se comportent en présence de congestion
C'est une idée fausse commune que les spinlocks ou sans verrouillage des algorithmes sont "généralement plus rapide", ou qu'ils ne sont utiles que pour les "très court tâches" (idéalement, un objet de synchronisation doivent être conservées plus longtemps que nécessaire, jamais).
La seule différence importante est de savoir comment les différentes approches comportent en présence de congestion.
Un système bien conçu a normalement peu ou pas de congestion (ce qui ne signifie pas tous les threads tentent d'acquérir le verrou à l'exact même temps). Par exemple, on pourrait normalement pas écrire du code qui acquiert un verrou, puis charge la moitié d'un mégaoctet de zip compressé des données à partir du réseau, décode et analyse les données, et enfin modifie une référence partagée (ajout de données à un conteneur, etc.) avant de relâcher le verrou. Au lieu de cela, on pourrait acquérir le verrou dans le seul but d'accéder à la ressource partagée.
Car cela signifie qu'il existe beaucoup plus de travail à l'extérieur de la section critique qu'à l'intérieur d'elle, naturellement, la probabilité pour un thread qui est à l'intérieur de la section critique est relativement faible, et donc quelques fils sont à la lutte pour le verrouiller en même temps. Bien sûr, chaque maintenant et puis les deux fils va essayer d'acquérir le verrou dans le même temps (si ce ne pouvais pas vous arrive, vous n'auriez pas besoin d'une serrure!), mais c'est l'exception plutôt que la règle dans une "bonne santé" du système.
Dans un tel cas, un spinlock grandement surpasse un sémaphore parce que si il n'y a pas de verrouillage de la congestion, les frais généraux de l'acquisition de la spinlock est une simple dizaine de cycles par rapport à des centaines/milliers de cycles pour un changement de contexte ou de 10 à 20 millions de cycles pour perdre le reste de la tranche de temps.
D'autre part, étant donné le niveau élevé d'encombrement, ou si le verrou est détenu pendant de longues périodes (parfois vous ne pouvez pas l'aider!), spinlock brûlera fou quantités de cycles CPU pour parvenir à rien.
Un sémaphore (ou mutex) est un bien meilleur choix dans ce cas, car elle permet à un thread différent pour exécuter utile tâches pendant ce temps. Ou, si aucun autre thread a quelque chose d'utile, il permet au système d'exploitation de ralentir le CPU et réduire la chaleur /économiser de l'énergie.
Aussi, sur un single-core, un système de spinlock sera tout à fait inefficace en présence de verrouillage de la congestion, comme un coup de fil de déchets de son temps à attendre un changement d'état qui ne peut pas arriver (pas jusqu'à la libération thread est prévue, qui n'est pas le cas tandis que le thread en attente en cours d'exécution!). Par conséquent, compte tenu de tout montant de contention, de l'acquisition du verrou prend environ 1 1/2 tranches de temps dans le meilleur des cas (en supposant que la libération fil conducteur est le suivant étant prévu), ce qui n'est pas un très bon comportement.
4. La façon dont ils sont mis en œuvre
Un sémaphore sera aujourd'hui enveloppez
sys_futex
sous Linux (éventuellement avec un spinlock qui se ferme après quelques tentatives).Spinlock est généralement mis en œuvre à l'aide d'opérations atomiques, et sans l'aide de rien fourni par le système d'exploitation. Dans le passé, cela signifie en utilisant soit le compilateur intrinsèques ou non-portable instructions en assembleur. Pendant ce temps les deux C++11 et C11 ont des opérations atomiques dans le cadre de la langue, donc, en dehors de la difficulté générale de l'écriture prouvable de verrouillage correct sans code, il est maintenant possible de mettre en œuvre sans verrouillage de code dans un lieu entièrement portable et (presque) sans douleur façon.
spin_trylock
, qui renvoie immédiatement avec un code d'erreur, si le verrou n'a pas pu être acquis. Un spin‑lock n'est pas toujours aussi sévère. Mais à l'aide despin_trylock
nécessite, pour une application, pour être bien conçu (probablement une file d'attente des opérations en attente, et ici, de choisir le prochain, laissant le réel dans la file d'attente).très simplement, un sémaphore est un "rendement" de la synchronisation de l'objet, spinlock est un "busywait' un. (il y a un peu plus de sémaphores en ce qu'elles synchroniser plusieurs threads, contrairement à un mutex ou de la garde ou à un moniteur ou une section critique qui protège une région de code à partir d'un seul thread)
Vous souhaitez utiliser un sémaphore dans plusieurs circonstances, mais l'utilisation d'un spinlock où vous allez à verrouiller pour un très court laps de temps - il y a un coût pour le verrouillage surtout si vous verrouillez beaucoup. Dans de tels cas, il peut être plus efficace de spinlock pour un peu de temps d'attente pour la ressource protégée pour devenir déverrouillé. Évidemment, il y a un gain de performance si vous tournez trop longtemps.
en règle générale, si vous faites tourner pendant plus d'un fil quantique, alors vous devriez utiliser un sémaphore.
Au-delà de ce Yoav Aviram et gbjbaanb dit, l'autre point clé est utilisé pour être que vous n'auriez jamais utiliser un spin-lock sur une machine mono-PROCESSEUR, alors qu'un sémaphore aurait du sens sur une telle machine. Aujourd'hui, vous êtes souvent du mal à trouver une machine sans noyaux multiples, ou de l'hyperthreading, ou l'équivalent, mais dans les circonstances que vous avez juste un seul PROCESSEUR, vous devez utiliser les sémaphores. (J'ai confiance en la raison en est évidente. Si le CPU est occupé attente de quelque chose d'autre pour libérer le spin-lock, mais il est en cours d'exécution sur le seul CPU, la serrure est peu probable d'être libéré jusqu'à ce que le processus ou thread est interrompu par l'O/S, ce qui peut prendre un certain temps et que rien d'utile ne se passe jusqu'à ce que le droit de préemption se produit.)
De Linux Pilotes de Périphérique par Rubinni
Je ne suis pas un noyau d'experts, mais voici quelques points:
Même machine monoprocesseur pouvez utiliser le spin-serrures si le noyau de préemption est activé lors de la compilation du noyau. Si le noyau de préemption est désactivé alors spin-lock (peut-être) se développe à une vide déclaration.
Aussi, lorsque nous essayons de comparer Sémaphore vs Spin-lock, je crois sémaphore se réfère à celui utilisé dans le noyau et non PAS celui utilisé pour la CIB (userland).
Fondamentalement, le spin-lock doit être utilisé si la section critique est petite (plus petite que la surcharge du sommeil et de réveil) et de la section critique ne fait pas appel à tout ce qui peut dormir! Un sémaphore doit être utilisé si la section critique est plus grand et il peut dormir.
Raman Chalotra.
Spinlock se réfère à une mise en œuvre de l'inter-thread de verrouillage à l'aide dépend de la machine des instructions de montage (comme test-and-set). Il est appelé un spinlock parce que le thread attend tout simplement dans une boucle ("spins") la vérification à plusieurs reprises jusqu'à ce que le verrou est mis à disposition (attente active). Spinlocks sont utilisées comme un substitut pour les mutex, qui sont une installation fournies par les systèmes d'exploitation (et non le CPU), parce que les spinlocks fonctionne mieux si elle est verrouillée pour une courte période de temps.
Un Semaphor est un service fourni par les systèmes d'exploitation pour l'IPC, à cet effet, son but principal est inter-processus-de la communication. Étant une installation fournies par le système d'exploitation c'est la performance ne sera pas aussi bonne que celle d'un spinlock pour l'inter-thead verrouillage (bien que possible). Les sémaphores sont mieux pour le verrouillage pendant de longues périodes de temps.
Que dit - mise en œuvre de splinlocks dans le montage est délicat, et pas portable.
Je voudrais ajouter mes observations, plus général et pas très spécifique à Linux.
En fonction de l'architecture de la mémoire et de la capacité du processeur, vous pourriez avoir besoin d'un spin-lock afin de mettre en œuvre un sémaphore sur un multi-core ou un système multiprocesseur, car dans de tels systèmes, une race condition peut se produire lorsque deux ou plusieurs threads/processus souhaitez acquérir un sémaphore.
Oui, si votre architecture de la mémoire propose le verrouillage d'une section de mémoire par un core/processeur retarder tous les autres accès, et si votre processeurs propose un test-and-set, vous pouvez mettre en œuvre un sémaphore sans un spin-lock (mais très bien!).
Cependant, en tant que simple/à bas prix multi-core systèmes sont conçus (je travaille dans les systèmes embarqués), toutes les architectures de mémoire de soutien tels multi-core/multiprocesseur caractéristiques, seul test-and-set ou l'équivalent. Puis une mise en œuvre pourrait être comme suit:
Libérer le sémaphore doit être mise en oeuvre comme suit:
Oui, et pour de simples sémaphores binaires sur un niveau de l'OS, il serait possible de n'utiliser qu'un spin-lock de remplacement. Mais seulement si le code-sections afin d'être protégés sont vraiment très petits.
Comme dit avant, si et quand vous mettez en place votre propre système d'exploitation, assurez-vous d'être prudent. Débogage de telles erreurs, c'est fun (à mon avis, n'est pas partagée par beaucoup), mais surtout très pénible et difficile.
Un "mutex" (ou "verrou d'exclusion mutuelle") est un signal que deux ou plusieurs processus asynchrones peuvent utiliser pour réserver une ressource partagée pour une utilisation exclusive. Le premier processus qui obtient la propriété de la "mutex" obtient également la propriété de la ressource partagée. D'autres processus doit attendre pour le premier processus de libération, c'est la propriété de la "mutex" avant qu'ils peuvent essayer de l'obtenir.
Le plus commun de verrouillage primitive dans le noyau est le spinlock. Le spinlock est très simple, seul détenteur de la serrure. Si un processus tente d'acquérir un spinlock et il n'est pas disponible, le processus va continuer d'essayer (la filature) jusqu'à ce qu'il peut acquérir le verrou. Cette simplicité crée une petite et rapide de serrure.
Spinlock est utilisé si et seulement si vous êtes sûr que votre résultat attendu se produira très peu de temps, avant votre fil d'exécution de la tranche de temps expire.
Exemple: Dans le module de pilote de périphérique, Le pilote écrit "0" dans le matériel le Registre R0 et maintenant, il faut attendre que R0 inscrire pour devenir 1. Le H/W lit le R0 et fait un peu de travail et de l'écrit "1" dans R0. C'est généralement rapide(micro-secondes). Maintenant, la filature est beaucoup mieux que d'aller dormir et a été interrompu par la H/W. bien sûr, tandis que la filature, le H/W condition d'échec doit être pris en charge!
Il n'y a absolument aucune raison pour qu'un utilisateur de l'application pour tourner. Il ne fait pas de sens. Vous vous apprêtez à tourner pendant un certain événement se produise et que l'événement doit être complété par un autre utilisateur de niveau application qui n'est jamais garanti d'arriver dans rapide laps de temps. Donc, je ne tourne pas du tout en mode utilisateur. Je ferais mieux de dormir() ou mutexlock() ou sémaphore lock() en mode utilisateur.
De quelle est la différence entre le spin des serrures et des sémaphores? par Maciej Piechotka:
Différence entre les sémaphores, mutex & spinlock?
Verrouillage dans Linux
verrou de rotation peut être occupé que par un seul processus, alors que le sémaphore peut être détenus par un ou plusieurs processus.
Verrou de rotation attendre jusqu'à ce que le processus libère un verrou, puis acquiert un verrou.
Sémaphore est en sommeil, je lock.e attend et va dormir.