Chapitre III : Ordonnancement des processus
Transcription
Chapitre III : Ordonnancement des processus
Systèmes d’Exploitation I Chapitre III : Ordonnancement des processus Amine DHRAIEF ESEN, Univ. Manouba Définition ● Lorsqu’un ordinateur est multiprogrammé, il possède fréquemment plusieurs processus/threads en concurrence pour l’obtention de temps processeur. – ● ● S’il n’y a qu’un seul processeur, un choix doit être fait quant au prochain processus à exécuter La partie du système d’exploitation qui effectue ce choix se nomme l’ordonnanceur (scheduler) et l’algorithme qu’il emploie s’appel algorithme d’ordonnancement (scheduling algorithm) Outre le fait de sélectionner le bon processus à exécuter, l’ordonnancement doit également se soucier de faire un usage efficace du processeur, car le passage d’un processus à l’autre sont coûteux en termes de temps de traitement 01/03/16 OS I 2 Quand ordonnancer ? ● Lorsqu’un nouveau processus est créé → il faut se décider s’il faut exécuter d’abord le processus parent ou le processus enfant. ● Lorsqu’un processus se termine → un autre processus doit être choisi parmi les processus prêts ● Lorsqu’un processus se bloque → un autre processus doit être sélectionner pour être exécuter ● Lorsqu’une interruption d’E/S se produit → il faut prendre une décision d’ordonnancement parmi les processus qui étaient bloqué en attente d’E/S. 01/03/16 OS I 3 Classification des algorithmes d'ordonnancement ● ● On peut classer les algorithmes d’ordonnancement selon leurs manière de réagir aux interruptions d’horloge – Non préemptif – Préemptif On utilise les interruptions pour commuter les tâches dans les systèmes multitâches. – Généralement, une interruption périodique est déclenchée par une horloge (souvent 100 ou 1 000 Hz), et l'ordonnanceur est alors mis en action. ● 1Hz = 1 cycle par seconde 01/03/16 OS I 4 Algorithmes d'ordonnancement non préemptif ● Sélectionne un processus, puis le laisse s’exécuter jusqu’à ce qu’il se bloque, ou qu’il libère volontairement le processeur – Même s’il s’exécute pendant des heures, il ne sera pas suspendu de force – Aucune décision d’ordonnancement n’intervient pendant les interruptions d’horloge 01/03/16 OS I 5 Algorithmes d'ordonnancement préemptif ● Sélectionne un processus et le laisse s’exécuter pendant un délai déterminé – si le processus est toujours en cours d’exécution à l’issue de ce délai, il est suspendu – l’ordonnancement sélectionne un autre processus à exécuter 01/03/16 OS I 6 Objectifs de l'ordonnanceur d'un système multi-utilisateur ● Les objectifs d'un ordonnanceur d'un système multiutilisateur sont entre autres : – S'assurer que chaque processus en attente d'exécution reçoive sa part de temps processeur. – Minimiser le temps de réponse. – Utiliser le processeur à 100%. – Utilisation équilibrée des ressources. – Prendre en compte des priorités. – Être prédictibles. 01/03/16 OS I 7 Ordonnanceurs non préemptifs ● ● Dans un système à ordonnancement non préemtif ou sans réquisition, le système d'exploitation choisit le prochain processus à exécuter: – le Premier Arrivé est le Premier Servi PAPS (ou First-Come First-Served FCFS) – ou le plus court d'abord (Short Job First SJF ) Il lui alloue le processeur jusqu'à ce qu'il se termine ou qu'il se bloque (en attente d'un événement). → Il n'y a pas de réquisition 01/03/16 OS I 8 Ordonnanceurs non préemptifs ● ● ● Si l'ordonnanceur fonctionne selon la stratégie SJF, il choisit, parmi le lot de processus à exécuter, le plus court (plus petit temps d'exécution). Cette stratégie est bien adaptée au traitement par lots de processus dont les temps maximaux d'exécution sont connus ou fixés par les utilisateurs car elle offre un meilleur temps moyen de séjour. Le temps de séjour d'un processus (temps de rotation ou de virement) est l'intervalle de temps entre la soumission du processus et son achèvement. 01/03/16 OS I 9 Ordonnanceurs non préemptifs ● Considérons par exemple un lot de quatre processus dont les temps respectifs d'exécution sont a, b, c, d – Le premier processus se termine au bout du temps a, – le deuxième processus se termine au bout du temps a+b, – le troisième processus se termine au bout du temps a+b+c, – le quatrième processus se termine au bout du temps a+b+c+d → Le temps moyen de séjour est t= (4a+3b+2c+d)/4 01/03/16 OS I 10 Exemple ● Considérons cinq travaux A, B, C, D et E, dont les temps d'exécution et leurs arrivages respectifs sont les suivants: 01/03/16 OS I 11 Exemple ● Faire un schéma qui illustre l’exécution et calculer le temps de séjour de chaque processus, le temps moyen de séjour, le temps d'attente et le temps moyen d'attente en utilisant : – Premier arrivé premier servi (PAPS) – Le plus court d'abord (SJF) 01/03/16 OS I 12 Exemple ● ● ● ● Au temps 0, seulement le processus A est dans le système et il s'exécute. Au temps 1 le processus B arrive mais il doit attendre qu'A termine car il a encore 2 unités de temps. Ensuite B s'exécute pendant 4 unités de temps. Au temps 4, 6, et 7 les processus C, D et E arrivent mais B a encore 2 unités de temps. Une 01/03/16 ● fois que B a terminé, C, D et EOSentrent au système dans l'ordre I 13 Exemple ● Le temps de séjour pour chaque processus est obtenu soustrayant le temps d'entrée du processus du temps de terminaison. Ainsi: 01/03/16 OS I 14 Exemple ● Le temps moyen de séjour est – ● (3+8+9+9+9)/5=7.6 Le temps d'attente est calculé soustrayant le temps d'exécution du temps de séjour : 01/03/16 OS I 15 Exemple ● Le temps moyen d'attente est – ● (0+2+5+7+8)/5=4.4 Il y a cinq tâches exécutées dans 16 unités de temps, alors 16/5=3.2 unité de temps par processus 01/03/16 OS I 16 Exemple ● ● Le plus court d'abord, schéma d'exécution : Pour la stratégie SJF nous aurons la séquence d'exécution A,B,E,D,C, et le temps de séjour est : 01/03/16 OS I 17 Exemple ● ● Le temps moyen d'attente est (0+2+2+4+8)/5 = 3.2 Il y a cinq tâches exécutées dans 16 unités de temps, alors 16/5=3.2 unité de temps par processus 01/03/16 OS I 18 Ordonnanceurs préemptifs ● ● ● ● Dans un schéma d'ordonnanceur préemptif, ou avec réquisition, pour s'assurer qu'aucun processus ne s'exécute pendant trop de temps, les ordinateurs ont une horloge électronique qui génère périodiquement une interruption. A chaque interruption d'horloge, le système d'exploitation reprend la main et décide si le processus courant doit poursuivre son exécution ou s'il doit être suspendu pour laisser place à un autre. S'il décide de suspendre son exécution au profit d'un autre, il doit d'abord sauvegarder l'état des registres du processeur avant de charger dans les registres les données du processus à lancer. C'est qu'on appelle la commutation de contexte ou le changement de contexte – Cette sauvegarde est nécessaire pour pouvoir poursuivre ultérieurement l'exécution du processus suspendu. 01/03/16 OS I 19 Ordonnanceurs préemptifs ● ● Le processeur passe donc d'un processus à un autre en exécutant chaque processus pendant quelques dizaines ou centaines de millisecondes. Le temps d'allocation du processeur au processus est appelé quantum. Cette commutation entre processus doit être rapide, c'est-à-dire, exiger un temps nettement inférieur au quantum 01/03/16 OS I 20 Ordonnanceurs préemptifs ● Le processeur, à un instant donné, n'exécute réellement qu'un seul processus, mais pendant une seconde, le processeur peut exécuter plusieurs processus et donne ainsi l'impression de parallélisme (pseudoparallélisme). 01/03/16 OS I 21 Ordonnancement du plus petit temps de séjour SRT ● ● ● L'ordonnancement du plus petit temps de séjour ou Shortest Remaining Time (SRT) est la version préemptive de l'algorithme SJF. Un processus arrive dans la file de processus, l'ordonnanceur compare la valeur espérée pour ce processus contre la valeur du processus actuellement en exécution. Si le temps du nouveau processus est plus petit, il rentre en exécution immédiatement. 01/03/16 OS I 22 Ordonnancement circulaire Round Robin ● ● L'algorithme du tourniquet, circulaire ou round robin est un algorithme ancien, simple, fiable et très utilisé. Il mémorise dans une file du type FIFO (First In First Out) la liste des processus prêts, c'est-à-dire en attente d'exécution. 01/03/16 OS I 23 Choix du processus à exécuter ● ● ● Il alloue le processeur au processus en tête de le, pendant un quantum de temps. Si le processus se bloque ou se termine avant la fin de son quantum, le processeur est immédiatement alloué à un autre processus (celui en tête de file). Si le processus ne se termine pas au bout de son quantum, son exécution est suspendue. Le processeur est alloué à un autre processus (celui en tête de file). Le processus suspendu est inséré en queue de file. Les processus qui arrivent ou qui passent de l'état bloqué à l'état prêt sont insérés en queue de file. 01/03/16 OS I 24 Choix de la valeur du quantum ● ● ● Un quantum trop petit provoque trop de commutations de processus et abaisse l'efficacité du processeur. Un quantum trop élevé augmente le temps de réponse des courtes commandes en mode interactif. Un quantum entre 20 et 50 ms est souvent un compromis raisonnable 01/03/16 OS I 25 Exemple ● ● Soient deux processus A et B prêts tels que A est arrivé en premier suivi de B, 2 unités de temps après. Les temps de processeur nécessaires pour l'exécution des processus A et B sont respectivement 15 et 4 unités de temps. Le temps de commutation est supposé nul. Calculer le temps de séjour de chaque processus A et B, le temps moyen de séjour, le temps d'attente, le temps moyen d'attente, et le nombre de changements de contexte pour: – SRT – Round robin (quantum = 10 unités de temps) – Round robin (quantum = 3 unités de temps) 01/03/16 OS I 26 Exemple 01/03/16 OS I 27 Exemple 01/03/16 OS I 28 Exemple 01/03/16 OS I 29 Ordonnancement avec priorité ● ● ● ● L'algorithme round robin permet une répartition équitable du processeur. Cependant il n'est pas intéressant si certains processus sont plus importants ou urgents que d'autres. L'ordonnanceur à priorité attribue à chaque processus une priorité. Le choix du processus à élire dépend des priorités des processus prêts. Les processus de même priorité sont regroupés dans une le du type FIFO. – Il y a autant de files qu'il y a de niveaux de priorité. – L'ordonnanceur choisit le processus le plus prioritaire qui se trouve en tête de file. – En général, les processus de même priorité sont ordonnancés selon l'algorithme du tourniquet. 01/03/16 OS I 30 Attribution et évolution des priorités ● ● ● Pour empêcher les processus de priorité élevée de s'exécuter indéfiniment, l'ordonnanceur diminue régulièrement la priorité du processus en cours d'exécution. La priorité du processus en cours est comparée régulièrement à celle du processus prêt le plus prioritaire (en tête de file). Lorsqu'elle devient inférieure, la commutation a lieu. Dans ce cas, le processus suspendu est inséré en queue de le correspondant à sa nouvelle priorité. L'attribution et l'évolution des priorités dépendent des objectifs fixés et de beaucoup de paramètres. 01/03/16 OS I 31 ORDONNANCEMENT DES PROCESSUS SOUS LINUX 01/03/16 OS I 32 États d'un processus 01/03/16 OS I 33 États d'un processus 01/03/16 OS I 34 États d'un processus ● ● ● ● Dans l'exemple suivant, nous allons faire passer un processus – et son fils - par tous ces stades. Tout d'abord, notre processus va consulter son propre état dans le pseudo-système de fichiers /proc, puis il va se scinder avec fork( ) avant de s'endormir pendant quelques secondes (en attente donc d'un signal de réveil). Son fils profitera de ce laps de temps pour afficher l'état du père, puis se terminera immédiatement. A son réveil, le processus père examinera l'état de son fils avant et après avoir lu le code de retour. Ensuite, le processus se met en sommeil, en attente d'une saisie de caractères 01/03/16 OS I 35 États d'un processus 01/03/16 OS I 36 États d'un processus 01/03/16 OS I 37 États d'un processus 01/03/16 OS I 38 Fonctionnement multitâche, priorités ● ● Jusqu'à présent, nous avons considéré que le processus est seul, qu'il s'exécute sur un processeur qui lui est attribué. Cela peut être le cas sur une machine multiprocesseur (SMP) peu chargée, mais c'est rare. Sur un système multitâche, l'accès au processeur est une ressource comme les autres (mémoire, disque, terminaux, imprimantes...) qui doit se partager entre les processus concurrents. 01/03/16 OS I 39 Fonctionnement multitâche, priorités ● Le noyau est chargé d'assurer la commutation entre les différents programmes pour leur offrir l'accès au processeur – ● Les transitions entre états que nous avons vues plus haut se passent toujours par l'intermédiaire d'un appel-système ou de l'arrivée d'un signal. – ● C'est très facile lorsqu'un processus s'endort. Le noyau a toujours le contrôle total de l'état des processus. Lorsque l'un d'eux s'endort, en attente d'une saisie de l'opérateur par exemple, le noyau peut alors élire un autre programme pour lui attribuer l'accès au processeur. – Seulement ce n'est pas encore suffisant, on ne peut guère compter sur la bonne volonté de chaque processus pour s'endormir régulièrement pour laisser un peu de temps CPU disponible pour les autres. La moindre erreur de programmation du genre while (1); bloquerait totalement le 01/03/16 OS I système. – 40 Fonctionnement multitâche, priorités ● ● ● ● Pour éviter ce problème, le noyau doit interrompre au bout d'un certain temps un processus qui s'exécute sans avoir besoin de s'endormir (en effectuant des calculs par exemple), afin qu'il cède la place à un autre programme. On dit que le noyau réalise une préemption du processeur, ce qui a donné naissance au terme de multitâche préemptif. Avec ce mécanisme, le noyau peut intervenir lorsqu'un processus dépasse le quantum de temps qui lui est imparti (par défaut 210 ms avec Linux). Le processus passe alors à l'état Prêt. Un processus prêt est donc simplement un processus en cours d'exécution qui a été suspendu par le noyau et qui reprendra son travail dès que celui-ci lui réaffectera le processeur. 01/03/16 OS I 41 Fonctionnement multitâche, priorités ● ● Au niveau de la commande ps ou du pseudo-fichier /proc/<pid>/status, il n'y a aucune différence entre un processus effectivement en exécution et un processus prêt. – Ils sont tous deux indiqués par la lettre R. – Cela explique pourquoi la commande «ps aux» présente parfois une liste contenant simultanément plusieurs processus à l'état R sur une machine uni-processeur. Un corollaire de ce mécanisme est qu'un processus qui se réveille, par exemple à cause d'une opération d'entrée-sortie terminée ou de l'arrivée d'un signal, ne passe pas directement de l'état Sommeil à l'état Exécution, mais passe par un état transitoire Prêt, et c'est l'ordonnanceur qui décidera du véritable passage en Exécution. Une application n'a donc habituellement aucune raison de se soucier de l'ordonnancement assuré par le noyau, tout se passe de manière totalement transparente. Un processus a toujours l'impression d'être 01/03/16 OS I en cours d'exécution ● 42 Fonctionnement multitâche, priorités ● ● Malgré tout, il faut être conscient qu'une application qui effectue de larges plages d'opérations sans réclamer d'entrée-sortie emploie beaucoup la seule ressource qui soit vraiment indispensable pour tous les processus : le CPU. Cette application pénalisera donc les autres logiciels qui font un usage plus raisonnable du processeur. Le noyau utilise, pour pallier ce problème, le principe de priorité double. – ● Une valeur statique de priorité est donnée à tout processus dès son démarrage et peut partiellement être corrigée par un appel-système approprié. L'ordonnanceur se sert de cette valeur statique pour calculer une nouvelle valeur, nommée priorité dynamique, et qui est remise à jour à chaque fois que le processus est traité par l'ordonnanceur. 01/03/16 OS I 43 Fonctionnement multitâche, priorités ● ● Cette priorité dynamique est entièrement interne au noyau et ne peut pas être modifiée. – Plus un processus utilise le temps CPU qui lui est imparti, plus le noyau diminue sa priorité dynamique. – Au contraire, plus le processus rend vite la main lorsqu'on l'exécute, plus le noyau augmente sa priorité. Avec cette politique, les tâches qui exploitent peu le processeur – déclenchant une opération d'entrée-sortie et s'endormant aussitôt en attente du résultat passeront beaucoup plus rapidement de l'état Prêt à l'Exécution effective que les tâches qui grignotent tous les cycles CPU qu'on 01/03/16 leur offre, sans jamais redonner OS I la main volontairement. – 44 Fonctionnement multitâche, priorités ● ● ● Plus un processus a une priorité dynamique élevée, plus la tranche de temps qu'on lui allouera sera longue . C'est un moyen de punir les programmes qui bouclent, en les laissant travailler quand même, mais sans trop perturber les autres processus. Lorsqu'un processus a consommé tous ses cycles, il ne sera réélu pour l'accès au processeur que dans le cas où aucun autre processus plus courtois n'est prêt. Lorsqu'un processus désire influer sur sa propre priorité statique, il peut utiliser l'appel système nice( ). On indique à celui-ci la «gentillesse» dont le processus appelant désire faire preuve. La déclaration de cette fonction se trouve dans <unistd.h>: int nice (int increment) ; 01/03/16 OS I 45 Fonctionnement multitâche, priorités ● La valeur transmise est ajoutée à notre gentillesse vis-à-vis des autres processus. – ● Cela signifie qu'un incrément positif diminue la priorité du processus, alors qu'un incrément négatif augmente sa priorité. La plage de valeur utilisée en interne par l'ordonnanceur pour les priorités statiques s'étale de 0 à 40. Toutefois, par convention on présente la gentillesse d'un processus sur une échelle allant de -20 (processus très égoïste) à +20, la valeur 0 étant celle par défaut. 01/03/16 OS I 46 Les mécanismes d'ordonnancement sous Linux ● ● ● ● Il existe trois types d'ordonnancement. En fait, il n'y a qu'un seul ordonnanceur, mais il choisit ou il rejette les processus selon trois politiques possibles. La configuration se fait processus par processus. Elle n'est pas nécessairement globale. Par contre, la modification de la politique d'ordonnancement associée à un processus est une opération privilégiée, car il existe un — gros — risque de bloquer complètement le système. Les trois algorithmes d'ordonnancement sont nommés FIFO, RR et OTHER 01/03/16 OS I 47 Ordonnancement sous algorithme FIFO ● ● ● ● L'algorithme FIFO est celui d'une file d'attente (First In First Out— premier arrivé, premier servi). Dans cette optique, il existe une liste des processus pour chaque priorité statique. Le premier processus de la priorité la plus haute s'exécute jusqu'à ce qu'il relâche le processeur. Il est alors repoussé à la fin de la liste correspondant à sa priorité. Si un autre processus de même priorité est prêt, il est élu. Sinon. l'ordonnanceur passe au niveau de priorité inférieur et en extrait le premier processus prêt. Ce mécanisme se répète indéfiniment. Dès qu'un processus de priorité supérieure à celui qui est en cours d'exécution est de nouveau prêt (parce qu'il attendait une entrée-sortie qui vient de se terminer par exemple), l'ordonnancement lui attribue immédiatement le processeur. 01/03/16 OS I 48 Ordonnancement sous algorithme FIFO ● ● ● ● Il existe un appel-système particulier, sched_yield( ), qui permet à un processus en cours d'exécution de relâcher volontairement le processeur. L'ordonnanceur peut alors faire tourner un autre processus du même niveau de priorité, s'il y en a un qui est prêt. Par contre, si aucun autre processus de même niveau n'est prêt à s'exécuter, le processeur est réattribué au processus qui vient d'invoquer sched_yield( ). Le noyau n'élit jamais un processus si un autre de priorité supérieure est prêt. Cet ordonnancement est le plus violent et le plus égoïste qui soit. Le plus fort a toujours raison. Le processus le plus prioritaire a toujours le processeur dès qu'il est prêt à s'exécuter. Il existe bien entendu un très sérieux risque de blocage du système (du moins sur une machine uni- processeur) si on exécute un simple while (1); 01/03/16 OS I 49 Ordonnancement sous algorithme FIFO ● ● ● Un programme se trouvant seul au niveau de priorité FIFO le plus élevé est sûr de s'exécuter de bout en bout sans être perturbé. Par contre, si deux processus s'exécutent au même niveau FIFO, la progression parallèle des deux n'est pas très prévisible. La commutation s'effectue parfois volontairement, en invoquant sched_yield( ) , et parfois sur des appels-système bloquants qui endorment un processus. Le comportement d'un processus seul est presque totalement déterministe (aux retards induits par les interruptions matérielles près). Cela permet d'assurer un comportement temps-réel quasi parfait. – Par contre, deux processus concurrents à même priorité ont des progressions imprévisibles. Pour améliorer tout cela, un second type d'ordonnancement temps-réel a été définit 01/03/16 OS I 50 Ordonnancement sous algorithme RR ● ● ● ● L'ordonnancement RR (Round Robin, tourniquet) est une simple variante de celui qui a été décrit précédemment, incorporant un aspect préemptif au temps partagé. Chaque processus se voit attribuer une tranche de temps fixe. Lorsqu'il a atteint sa limite, le noyau l'interrompt et le met en état Prêt. Ensuite, il le repousse à la fin de la liste des processus associée à sa priorité. Si un autre processus du même niveau est prêt, il sera choisi. Si aucun autre processus de même priorité n'est prêt, le noyau redonne la main au programme qu'il vient d'interrompre. On ne donne jamais le processeur à un processus de plus faible priorité. La différence avec l'algorithme FIFO réside donc uniquement dans le cas où plusieurs processus sont simultanément prêts avec la même priorité (et si aucun processus de plus haute priorité n'est prêt). 01/03/16 OS I 51 Ordonnancement sous algorithme RR ● ● ● Dans le cas de l'algorithme FIFO, le premier processus qui arrive reçoit le processeur et le conserve jusqu'à ce qu'il s'endorme ou qu'il le relâche volontairement avec sched_yield( ). Avec l'ordonnancement RR, chaque processus prêt de la plus haute priorité sera régulièrement choisi pour s'exécuter, quitte à interrompre l'un de ses confrères qui ne veut pas s'arrêter de luimême. Si deux processus ont la même priorité, chacun aura donc l'impression de s'exécuter deux fois moins vite que s'il était seul, mais aucun des deux ne sera bloqué pour une période a priori inconnue, comme c'était le cas avec l'ordonnancement FIFO 01/03/16 OS I 52 Ordonnancement sous algorithme OTHER ● ● ● ● Le troisième type d'ordonnancement est l'algorithme OTHER (autre), qui n'est pas réellement défini par Posix.1b. L'implémentation de cet algorithme est laissée à la discrétion des concepteurs du noyau. Sur certains systèmes, il peut s'agir d'ailleurs de l'algorithme RR, avec des plages de priorité plus faibles. Sous Linux, il s'agit de l'ordonnancement utilisant une priorité dynamique recalculée en fonction de la priorité statique et de l'usage que le processus fait du laps de temps qui lui est imparti. Il est important de savoir que les algorithmes dits temps-réel (FIFO et RR) ont des plages de priorité qui sont toujours supérieures à celles des processus s'exécutant avec l'algorithme OTHER. 01/03/16 OS I 53 Politique d'ordonnancement ● ● ● Les sources habituelles d'informations traitant des processus (ps, top, /proc/<pid>/...) ne nous indiquent pas la politique d'ordonnancement avec laquelle s'exécute un programme. Nous allons donc créer un petit programme qui va nous servir de frontal pour l'appel-système sched_getscheduler(). Tous les appels-système que nous allons étudier ici sont définis par la norme Posix. l b et sont déclarés dans <sched.h> : int sched_getscheduler (int pid); Cet appel-système renvoie -l en cas d'erreur, sinon il renvoie l'une des trois constantes SCHED_FIFO, SCHED_RR ou SCHED_OTHER, en fonction de l'ordonnancement du processus dont on fournit le PID. Si on passe un PID nul, cette fonction renvoie la politique du processus appelant 01/03/16 OS I 54 Politique d'ordonnancement 01/03/16 OS I 55 Politique d'ordonnancement 01/03/16 OS I 56 The END 01/03/16 OS I 57