Dupliqué possible: strong>
Pourquoi ne pouvez-vous pas dormir pendant que vous tenez Spintlock? P> blockQuote>Autant que je sache, les spinlocks doivent être utilisés à courte durée et ne sont que des choix de code tels que le gestionnaire d'interruption où dormir (préemption) n'est pas autorisé. P>
Cependant, je ne sais pas pourquoi il y a une telle "règle" qu'il ne devrait pas y avoir de sommeil tout en maintenant un spinlock. Je sais que ce n'est pas une pratique recommandée (puisqu'elle est préjudiciable au rendement), mais je ne vois aucune raison pour que les dormeurs ne soient pas autorisés dans des spinlocks. P>
Vous ne pouvez pas tenir une serrure de spin pendant que vous achetez un sémaphore, car vous pourriez avoir à dormir en attendant le sémaphore et que vous ne pouvez pas dormir en tenant une serrure de spin (du développement du noyau Linux »de Robert Love). p> blockQuote>
La seule raison pour laquelle je peux voir est pour des raisons de portabilité, car dans des uniprocesseurs, les spinlocks sont mis en œuvre comme des interruptions invalidantes et par des interruptions désactivées, le sommeil n'est bien sûr pas autorisé (mais le sommeil ne brisera pas le code dans les systèmes SMP). p>
Mais je me demande si mon raisonnement est correct ou s'il y a une autre raison. P>
3 Réponses :
Il y a plusieurs raisons pour lesquelles, du moins sous Linux, dormir dans des spinlocks n'est pas autorisé: P>
Utilisez le bon outil pour le bon travail - si vous avez besoin de dormir, des sémaphores et des mutex sont vos amis. P>
En fait, des sémaphores ne doivent vraiment pas être utilisés dans le code du noyau, à moins que vous n'ayez un cas d'utilisation très spécialisé (vraiment si vous lisez cette question sur Stackoverflow, vous n'avez pas besoin de sémaphores :) Utilisez simplement des mutexs pour le verrouillage lorsque vous devez dormir, et Spinlocks Lorsque vous devez verrouiller dans un contexte non drable.
@bdonlan j'ai un doute sur le point 1. Vous avez dit que le fil A de ne vous réveillera jamais? Pourquoi donc? Lorsque la tranche de temps pour le fil B finira et le temps de sommeil pour le fil aurait fini, le filetage A exécuterait l'utilisation de sa tranche de temps et une fois terminée, libérera la serrure. N'est-ce pas le cas?
@Sumittrehan: bon point. Si le Spinlock n'est pas quelque chose d'essentiel au planificateur lui-même et que le thread b n'était pas dans le contexte d'interruption et n'a pas eu d'interruption ni de préemption désactivée, puis finalement enfiler B pourrait être préempté. Cependant, sous Linux, la préemption est toujours désactivée lorsqu'un spinlock est tenu (ou sur le point d'être tenu). C'est parce que si un thread contient un spinlock tout en ne courant, d'autres threads gaspillent beaucoup de temps tournant sur la serrure, et il y a un potentiel d'impasse avec des gestionnaires d'interruption. Donc, dans la réalité, le fil b ne sera pas préemptible et sera une impasse.
@bdonlan: Pouvez-vous expliquer ce cas: nous n'avons qu'un seul noyau, A: Holding Spin Lock, B attendant la serrure de spin (probablement be dort). L'interruption est en train de tirer. A maintenant devrait être dormir. Une fois le gestionnaire d'interruption est terminé, lequel prendra le spinlock, A ou B?
La préemption @Hoangpham n'est pas autorisée alors qu'un spinlock est tenu, la fois après que l'interruption achève les retours d'exécution à A. Notez qu'un pas i> se couche (un commutateur de contexte ne se produit pas)
Merci @bdonlan. Si A est en cours d'exécution, et A et B ne contiennent aucune serrure. Une fois l'interruption terminée l'exécution, il est possible d'avoir une préemption (B obtenir la CPU) est-ce correct?
En fait, vous peut-il em> dormir avec des interruptions désactivées ou une autre sorte d'exclusion active. Si vous ne le faites pas, la condition pour laquelle vous dormez pourrait changer d'état en raison d'une interruption et que vous ne vous réveilleriez jamais. Le code de sommeil ne serait normalement jamais entré sans em> une priorité élevée ou une autre section critique qui renferme le chemin d'exécution entre la décision de sommeil et le commutateur de contexte. P> li>
mais pour les spinlocks, le sommeil est un désastre, car le verrou reste défini. D'autres threads vont tourner quand ils l'ont frappé et ils n'arrêteront pas de tourner avant de vous réveiller du sommeil. Cela pourrait être une éternité comparée à la poignée de tours attendue dans le pire des cas dans un spinlock, car les spirlocks existent simplement pour synchroniser l'accès aux emplacements de mémoire, ils ne sont pas censés interagir avec le mécanisme de commutation de contexte.
> (Pour cette affaire, tous les autres threads pourraient éventuellement frapper le spinlock, puis vous auriez coincé chaque fil de chaque noyau de tout le système.) P> li>
ul>
Pouvez-vous élaborer le premier point?
Le premier point est faux. Vous ne pouvez pas dormir avec des interruptions handicapées; Pour faire face aux courses allusion à là, faites des choses dans le bon ordre: définissez votre état sur Task_Interruptible, vérifiez la condition, puis calendrier () code> - ou simplement utiliser
wait_event () code>, qui gère ceci pour vous.
@Roland, je faisais simplement référence au point de vue du code de processus du noyau, de sorte que vous peut, i> dans le sens de l'appel d'un calendrier () code> ou
dormir () code> point d'entrée. Le mécanisme de sommeil du noyau permettra de réactiver les interruptions. Tous les noyaux communs sont désormais SMP, les interruptions invalidantes n'appartiennent pas beaucoup plus, mais certainement, il n'exécutera aucun matériel Wait-for-interruption i> instructions sans réactivation d'interruptions.
Vous ne pouvez pas quand vous utilisez une serrure de spin car elle est censée être utilisée. Les serrures de spin sont utilisées lorsque vous devez vraiment protéger les régions critiques et les structures de données partagées. Si vous l'acquérez un tout en maintenant un sémaphore, vous verrouillez l'accès à la région critique (disons) Votre verrou est attachée à (il s'agit généralement d'un membre d'une structure de données plus grande spécifique), tout en permettant à ce processus d'éventuellement dormir. Si, par exemple, un IRQ est soulevé pendant que ce processus dort, et le gestionnaire IRQ a besoin d'accéder à la région critique toujours enfermée, elle est bloquée, qui ne peut jamais arriver avec IRQS. Évidemment, vous pouvez faire des exemples dans lesquels votre serrure de spin n'utilise pas la façon dont il devrait être (une serrure de spin hypothétique attachée à une boucle NOP); Mais ce n'est tout simplement pas un vrai verrou de spin trouvé dans les noyaux Linux. P>
Quelle est cette règle que vous parlez de?
Je viens d'ajouter une citation de bloc d'un livre où mon QUSTION est découvert.
Cela me semble que quelque chose de spécifique au développement du noyau Linux. Si vous parlez du développement du noyau Linux, veuillez étiqueter la question en conséquence.