GNU/Linux >> Tutoriels Linux >  >> Linux

Qu'est-ce que cela signifie de dire que le noyau Linux est préemptif ?

Les noyaux Unix traditionnels avaient un verrou unique, qui était détenu par un thread pendant que le code du noyau était en cours d'exécution. Par conséquent, aucun autre code du noyau ne pourrait interrompre ce thread.

Cela a facilité la conception du noyau, car vous saviez que si un thread utilisait les ressources du noyau, aucun autre thread ne l'était. Par conséquent, les différents threads ne peuvent pas gâcher le travail des autres.

Dans les systèmes à processeur unique, cela ne pose pas trop de problèmes.

Cependant, dans les systèmes multiprocesseurs, vous pourriez avoir une situation où plusieurs threads sur différents processeurs ou cœurs voulaient tous exécuter le code du noyau en même temps. Cela signifie qu'en fonction du type de charge de travail, vous pouvez avoir de nombreux processeurs, mais tous passent le plus clair de leur temps à s'attendre les uns les autres.

Dans Linux 2.6, les ressources du noyau étaient divisées en unités beaucoup plus petites, protégées par des verrous individuels, et le code du noyau était revu pour s'assurer que les verrous n'étaient maintenus que lorsque les ressources correspondantes étaient utilisées. Désormais, différents processeurs n'ont plus qu'à s'attendre s'ils veulent accéder à la même ressource (par exemple une ressource matérielle).


Avant la version 2.5.4 du noyau Linux, le noyau Linux n'était pas préemptif, ce qui signifie qu'un processus exécuté en mode noyau ne peut pas être déplacé hors du processeur jusqu'à ce qu'il quitte lui-même le processeur ou qu'il commence à attendre qu'une opération d'entrée-sortie soit terminée.

Généralement, un processus en mode utilisateur peut entrer en mode noyau à l'aide d'appels système. Auparavant, lorsque le noyau n'était pas préemptif, un processus de priorité inférieure pouvait inverser en priorité un processus de priorité supérieure en lui refusant l'accès au processeur en appelant à plusieurs reprises des appels système et en restant en mode noyau. Même si la tranche de temps du processus de priorité inférieure expirait, il continuerait à s'exécuter jusqu'à ce qu'il termine son travail dans le noyau ou abandonne volontairement le contrôle. Si le processus prioritaire en attente d'exécution est un éditeur de texte dans lequel l'utilisateur est en train de taper ou un lecteur MP3 prêt à remplir sa mémoire tampon audio, le résultat est une mauvaise performance interactive. De cette façon, le noyau non préemptif était un inconvénient majeur à l'époque.


Imaginez la vue simple du multitâche préemptif. Nous avons deux tâches utilisateur, toutes deux exécutées en permanence sans utiliser d'E/S ni effectuer d'appels au noyau. Ces deux tâches n'ont rien à faire de spécial pour pouvoir s'exécuter sur un système d'exploitation multitâche. Le noyau, généralement basé sur une interruption de minuterie, décide simplement qu'il est temps pour une tâche de s'arrêter pour en laisser une autre s'exécuter. La tâche en question ignore complètement ce qui s'est passé.

Cependant, la plupart des tâches font des requêtes occasionnelles au noyau via des appels système. Lorsque cela se produit, le même contexte utilisateur existe, mais le processeur exécute le code du noyau pour le compte de cette tâche.

Les noyaux Linux plus anciens n'autoriseraient jamais la préemption d'une tâche pendant qu'elle était occupée à exécuter le code du noyau. (Notez que les opérations d'E/S sont toujours volontairement replanifiées. Je parle d'un cas où le code du noyau a des opérations gourmandes en CPU comme le tri d'une liste.)

Si le système permet à cette tâche d'être préemptée lorsqu'il exécute le code du noyau, alors nous avons ce qu'on appelle un "noyau préemptif". Un tel système est immunisé contre les retards imprévisibles qui peuvent être rencontrés lors des appels système, il pourrait donc être mieux adapté aux tâches embarquées ou en temps réel.

Par exemple, si sur un processeur particulier, il y a deux tâches disponibles, et l'une prend un appel système qui prend 5 ms pour se terminer, et l'autre est une application de lecteur MP3 qui doit alimenter le tuyau audio toutes les 2 ms, vous pourriez entendre un son saccadé.

L'argument contre la préemption est que tout le code du noyau qui pourrait être appelé dans le contexte de la tâche doit pouvoir survivre à la préemption - il y a beaucoup de code de pilote de périphérique médiocre, par exemple, qui pourrait être mieux s'il est toujours capable de terminer une opération avant permettant à une autre tâche de s'exécuter sur ce processeur. (Avec les systèmes multiprocesseurs la règle plutôt que l'exception de nos jours, tout le code du noyau doit être réentrant, de sorte que cet argument n'est pas aussi pertinent aujourd'hui.) De plus, si le même objectif pouvait être atteint en améliorant les appels système avec de mauvais latence, la préemption n'est peut-être pas nécessaire.

Un compromis est CONFIG_PREEMPT_VOLUNTARY, qui permet un changement de tâche à certains points du noyau, mais pas partout. S'il n'y a qu'un petit nombre d'endroits où le code du noyau peut s'enliser, c'est un moyen peu coûteux de réduire la latence tout en gardant la complexité gérable.


La préemption permet au noyau de donner l'IMPRESSION du parallélisme :vous n'avez qu'un seul processeur (disons il y a dix ans), mais vous avez l'impression que tous vos processus s'exécutent simultanément. C'est parce que le noyau préempte (c'est-à-dire retire l'exécution de) l'exécution d'un processus pour la donner au suivant (peut-être en fonction de leur priorité).

MODIFIER Les noyaux non préemptifs attendent que les processus rendent la main (c'est-à-dire pendant les appels système), donc si votre processus calcule beaucoup de données et n'appelle aucun type de yield fonction, les autres processus ne pourront pas s'exécuter pour exécuter leurs appels. De tels systèmes sont dits coopératifs car ils demandent la coopération des processus pour assurer l'équité du temps d'exécution

MODIFICATION 2 L'objectif principal de la préemption est d'améliorer la réactivité du système entre plusieurs tâches, ce qui est bon pour les utilisateurs finaux, alors que d'un autre côté, les serveurs veulent atteindre le débit le plus élevé, donc ils n'en ont pas besoin :(de la configuration du noyau Linux)

  • Noyau préemptif (bureau à faible latence)
  • Préemption volontaire du noyau (bureau)
  • Pas de préemption forcée (serveur)

Linux
  1. Que signifie __init dans le code du noyau Linux ?

  2. Que signifie EXPORT_SYMBOL dans le code du noyau Linux ?

  3. Quel est le meilleur int 0x80 ou syscall en code 32 bits sous Linux ?

  4. Comment coder un module du noyau Linux ?

  5. Que fait si [[ $ ? -ne 0 ]] ; signifie en .ksh

Qu'est-ce que null signifie dans Linux et l'informatique

Que signifie la commande Cat sous Linux ?

Que faire en cas de panique du noyau Linux

Linux - Que signifie un point après les bits d'autorisation de fichier ?

Linux - Que voulons-nous dire exactement lorsque nous disons que nous utilisons Linux ?

Que signifie le suffixe .d sous Linux ?