Quand doit-on utiliser un spinlock au lieu de mutex?
Je pense que les deux font le même travail,comment voulez-vous décider laquelle utiliser pour la synchronisation?
- double possible de Spinlock Contre Sémaphore!
- Mutex et Sémaphore ne sont pas la même chose, donc je ne pense pas que c'est un doublon. La Réponse de l'article référencé états correctement. Pour plus de détails, voir barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore
Vous devez vous connecter pour publier un commentaire.
La Théorie
En théorie, lorsqu'un thread tente de verrouiller un mutex et il n'y réussit pas, parce que le mutex est déjà verrouillé, il va aller dormir, immédiatement en permettant à un autre thread à exécuter. Il va continuer à dormir jusqu'à s'être réveillé, ce qui sera le cas une fois que le mutex est déverrouillé par ce fil était maintenant le verrou avant. Lorsqu'un thread tente de verrouillage spinlock et elle n'y parvient pas, il sera constamment re-essayez de le verrouiller, jusqu'à ce qu'il réussisse enfin; ainsi, il ne sera pas permettre à un autre thread pour prendre sa place (cependant, le système d'exploitation de force de passer à un autre thread, une fois que le CPU d'exécution quantique de le thread courant a été dépassé, bien sûr).
Le Problème
Le problème avec les mutex est que de mettre les fils de dormir et de se réveiller à nouveau deux sont plutôt des opérations coûteuses, ils ont besoin de beaucoup d'instructions du PROCESSEUR et donc aussi de prendre un peu de temps. Si maintenant le mutex a été verrouillée pour un très court laps de temps, le temps passé à mettre un fil de dormir et de se réveiller de nouveau risque de dépasser le temps que le thread a réellement dormi de loin et il pourrait même le dépasser à la fois le fil aurait perdu, en constante interrogation sur un spinlock. D'autre part, l'interrogation sur un spinlock sera constamment de perdre du temps de calcul et si le verrou est détenu pour un temps plus long, ce sera de perdre beaucoup plus de temps PROCESSEUR, et il aurait été beaucoup mieux si le fil était en train de dormir à la place.
La Solution
À l'aide de spinlocks sur un single-core/CPU unique système permet généralement pas de sens, car tant que le spinlock interrogation est bloquant le seul cœur de PROCESSEUR, aucun autre thread peut s'exécuter et depuis aucun autre thread peut s'exécuter, la serrure ne sera pas déverrouillée. OIE, un spinlock déchets CPU seulement de temps sur ces systèmes pour aucun avantage réel. Si le thread a été mis en sommeil au lieu de cela, un autre thread pourrait avoir couru à la fois, éventuellement, le déverrouillage de la serrure et en permettant que le premier thread à poursuivre le traitement, une fois qu'il se réveilla à nouveau.
Sur un multi-core et multi-processeurs, avec beaucoup de verrous détenus pour un très court laps de temps seulement, le temps perdu pour constamment mettre threads de dormir et de se réveiller à nouveau pourrait diminuer sensiblement les performances d'exécution. Lors de l'utilisation de spinlocks au lieu de cela, les fils d'avoir la chance de profiter de leur pleine exécution quantique (toujours seulement de bloquer pendant une très courte période de temps, mais ensuite immédiatement à poursuivre leur travail), conduisant à beaucoup plus élevée, le débit de traitement.
La Pratique
Puisque très souvent les programmeurs ne peuvent pas savoir à l'avance si les mutex ou spinlocks sera mieux (par exemple, parce que le nombre de coeurs de processeurs de l'architecture cible est inconnue), ni les systèmes d'exploitation de savoir si un morceau de code a été optimisé pour single-core ou multi-core environnements, la plupart des systèmes ne sont pas strictement la distinction entre les mutex et les spinlocks. En fait, la plupart des systèmes d'exploitation modernes ont hybrides mutex et hybride spinlocks. Que veut réellement dire?
Un hybride mutex se comporte comme un spinlock au premier sur un système multi-core. Si un thread ne peut pas verrouiller le mutex, il ne sera pas mis à dormir immédiatement, depuis le mutex peut être débloqué très vite, de sorte qu'au lieu que le mutex sera la première à se comporter exactement comme un spinlock. Seulement si le verrou n'a pas encore été obtenu après un certain laps de temps (ou de tentatives ou de toute autre mesure de facteur), le thread est vraiment mis à dormir. Si le même code s'exécute sur un système avec un seul core, le mutex n'spinlock, même si, comme, voir ci-dessus, qui ne serait pas bénéfique.
Un hybride spinlock se comporte comme un normal spinlock au premier abord, mais pour éviter de perdre trop de temps CPU, il peut avoir un back-off de la stratégie. Il sera normalement pas mettre le fil de sommeil (puisque vous ne voulez pas que cela se produise lors de l'utilisation d'un spinlock), mais il peut décider d'arrêter le fil (immédiatement ou après un certain laps de temps) et permettre à un autre thread à exécuter, augmentant ainsi les chances que le spinlock est déverrouillé (un pur fil de l'interrupteur est généralement moins coûteuse que celle qui consiste à mettre un fil de dormir et de se réveiller de nouveau plus tard, mais pas loin).
Résumé
En cas de doute, utiliser les mutex, ils sont en général le meilleur choix et le plus moderne des systèmes leur permettent de spinlock pour un très court laps de temps, si cela semble bénéfique. À l'aide de spinlocks peut parfois améliorer les performances, mais seulement sous certaines conditions et le fait que vous êtes dans le doute plutôt me dit, que vous ne travaillez pas sur tout projet actuellement où un spinlock pourrait être bénéfique. Vous pourriez envisager d'utiliser votre propre "verrouillage de l'objet", qui peut soit utiliser un spinlock ou un mutex en interne (par exemple, ce comportement pourrait être configurable lors de la création d'un tel objet), d'abord utiliser les mutex partout et si vous pensez que l'utilisation d'un spinlock quelque part peut vraiment aider, d'essayer et de comparer les résultats (par exemple à l'aide d'un profileur), mais assurez-vous de tester les deux cas, un seul cœur et d'un système multi-core avant de sauter à des conclusions (et, éventuellement, des systèmes d'exploitation différents si votre code sera cross-platform).
Mise à jour: Un Avertissement pour iOS
Fait pas l'iOS spécifique, mais iOS est la plate-forme où la plupart des développeurs peuvent faire face à ce problème: Si votre système dispose d'un planificateur de threads, cela ne garantit pas que n'importe quel thread, n'importe comment faible priorité peut être, finira par obtenir une chance de s'exécuter, puis spinlocks peut entrainer des blocages. L'iOS planificateur distingue différentes classes de fils et de fils sur une classe inférieure sera exécuté uniquement si aucun thread dans une classe supérieure, veut courir ainsi. Il n'y a pas de stratégie pour cela, donc si vous avez en permanence la haute classe de threads disponibles, de basse classe threads ne sera jamais tout le temps CPU et donc jamais la moindre chance d'effectuer des travaux.
Le problème apparaît comme suit: Votre code obtient un spinlock en low prio classe thread et alors qu'il est dans le milieu de la serrure, le quantum de temps est dépassée et que le thread s'arrête en cours d'exécution. La seule façon de comment cela spinlock peut être remis en liberté est si faible prio classe thread obtient le temps CPU de nouveau, mais ce n'est pas garanti d'arriver. Vous pouvez avoir un couple de la haute prio classe threads constamment souhaitez exécuter, et le planificateur des tâches toujours la priorité à ceux. L'un d'eux peut s'exécuter à travers le spinlock et essayer de l'obtenir, ce qui n'est pas possible, bien sûr, et le système va le faire céder. Le problème, c'est: Un thread qui a produit est immédiatement disponible pour l'exécution de nouveau! Avoir une plus grande priorité que le thread maintenant le verrou, le fil maintenant le verrou n'a aucune chance d'obtenir de l'UC de l'exécution. Soit un autre thread obtiendrez d'exécution ou le fil qui vient de donné.
Pourquoi ce problème se produit pas avec les mutex? Lorsque la haute priorité de thread ne peut pas obtenir le mutex, il ne sera pas le rendement, elle peut la faire tourner un peu, mais finira par être envoyé à dormir. Un thread en sommeil n'est pas disponible pour l'exécution jusqu'à ce qu'il est réveillé par un événement, par exemple un événement comme le mutex être déverrouillé, il a été en attente pour les. Apple est au courant de ce problème et a donc obsolète
OSSpinLock
comme un résultat. La nouvelle écluse est appeléos_unfair_lock
. Ce verrouillage permet d'éviter la situation mentionnée ci-dessus comme il est conscient de la thread différent classes de priorité. Si vous êtes sûr que l'utilisation de spinlocks est une bonne idée dans votre iOS de projet, de l'utilisation que l'on. Rester à l'écart deOSSpinLock
! Et en aucun cas mettre en place votre propre spinlocks dans iOS! En cas de doute, utiliser un mutex! macOS n'est pas affecté par ce problème, car il a un thread différent planificateur de ne pas permettre à n'importe quel thread (même à faible priorité des threads) de fonctionner à sec, sur le temps CPU, toujours la même situation peut survenir et il sera ensuite conduire à une mauvaise performance, ainsiOSSpinLock
est obsolète sur macOS ainsi.Continue avec Mecki à la suggestion de cet article pthread mutex vs pthread spinlock sur Alexander Sandler blog, Alex sur Linux montre comment le
spinlock
&mutexes
peut être mis en œuvre pour tester le comportement à l'aide de #ifdef.Cependant, assurez-vous de prendre l'appel final basée sur votre sens de l'observation, de la compréhension de l'exemple donné est un cas isolé, votre projet de l'exigence, de l'environnement peut être totalement différente.
Veuillez également noter que sur certains environnements et de conditions (par exemple en cours d'exécution sur windows lors de l'expédition de niveau >= l'ENVOI de NIVEAU), vous ne pouvez pas utiliser les mutex, mais plutôt spinlock.
Sur unix, même chose.
Ici est équivalent à la question sur concurrent stackexchange unix site:
https://unix.stackexchange.com/questions/5107/why-are-spin-locks-good-choices-in-linux-kernel-design-instead-of-something-more
Info sur l'envoi sur les systèmes windows:
http://download.microsoft.com/download/e/b/a/eba1050f-a31d-436b-9281-92cdfeae4b45/IRQL_thread.doc
Mecki réponse assez bien clous. Cependant, sur un seul processeur, à l'aide d'un spinlock peut avoir du sens lorsque la tâche est en attente du verrou à être donné par une Routine de Service d'Interruption. L'interruption serait de transférer le contrôle à l'ISR, qui serait prêt à la ressource pour l'utilisation par l'attente de la tâche. Il finirait par le déblocage de la serrure avant de donner le contrôle de l'interruption de la tâche. Le fait de tourner la tâche de trouver le spinlock disponibles et procéder.
Spinlock Mutex et de mécanismes de synchronisation sont très courantes aujourd'hui pour être vu.
Pensons Spinlock premier.
Fondamentalement, c'est une longue attente de l'action, ce qui signifie que nous devons attendre pour un verrou est libéré avant que nous puissions procéder à la prochaine action. Conceptuellement très simple, sa mise en œuvre n'est pas le cas. Par exemple: Si le verrou n'a pas été publié alors que le thread a été changer et entrer dans l'état de veille, doit faire face avec elle? Comment traiter avec les verrous de synchronisation lorsque deux threads simultanément une demande d'accès ?
En général, le plus intuitif idée est de traiter avec la synchronisation via une variable pour protéger de la section critique. Le concept de Mutex est similaire, mais ils sont toujours différents. Focus sur: l'utilisation de l'UC. Spinlock consomme du temps CPU à attendre pour faire l'action, et par conséquent, nous pouvons résumer la différence entre les deux:
Homogènes multi-core environnements, si le temps passé sur la section critique est petit que l'utilisation de Spinlock, parce que nous pouvons réduire le temps de changement de contexte. (Single-core, la comparaison n'est pas important, parce que certains systèmes de mise en œuvre de Spinlock au moyen de l'interrupteur)
Dans Windows, à l'aide de Spinlock mettra à niveau le fil au niveau dispatch_level, qui dans certains cas peut-être pas autorisé, donc cette fois, nous avons dû utiliser un Mutex (APC_LEVEL).
Ce qui est faux. Il n'y a pas de gaspillage de cycles de processeur en utilisant des spinlocks sur uni systèmes de processeur, car une fois qu'un processus prend un verrou de rotation , de préemption est désactivé , donc en tant que tel, il n'y aurait pas d'autre tournant! C'est juste que son utilisation n'a aucun sens! Par conséquent, les spinlocks sur Uni systèmes sont remplacés par preempt_disable au moment de la compilation par le noyau!