Les années 1960 ont constitué un tournant pour les système d'exploitation. Dans le cadre du projet MAC au MIT (Massachusset Institute of Technology), le système d'exploitation CTTS est publié en 1961. C'est l'un des tout premiers système d'exploitation à temps partagé, permettant à plusieurs utilisateurs d'utiliser un ordinateur en même temps. C'est une déclinaison du multitâche apparu peu de temps avant, et c'est cette apparente simultaneité dans l'exécution des programmes qui a permis de se diriger vers l'informatique moderne.
Dans les années 1970 les ordinateurs personnels n'étaient pas capables d'exécuter plusieurs tâches à la fois : on lancait un programme et on y restait jusqu'à ce que celui-ci plante ou se termine. Les systèmes d'exploitation récents (Windows, Linux ou osX par exemple) permettent d'exécuter plusieurs tâches simultanément - ou en tous cas, donner l'impression que celles-ci s'exécutent en même temps. A un instant donné, il n'y a donc pas un mais plusieurs programmes qui sont en cours d'exécution sur un ordinateur : on les nomme processus. Une des tâches du système d'exploitation est d'allouer à chacun des processus les ressources dont il a besoin en termes de mémoire, entrées-sorties ou temps processeur, et de s'assurer que les processus ne se gênent pas les uns les autres.
si l'on prend l'exemple du smartphone, cet ordinateur que l'on a dans la poche, alors que nous regardons une vidéo, il va suivre les antennes relais et se synchroniser avec, écouter s'il y a un appel téléphonique ou des SMS qui arrive, vérifier les nouveaux courriers électroniques, mettre à jour les notifications des différents réseaux sociaux,etc. Il y a toute une myriade de processus qui s'éxécute de façon «simultanée».
Nous avons tous été confrontés à la problématique de la gestion des processus dans un système d'exploitation, en tant qu'utilisateur :
Nous allons voir en détails dans cette séquence comment les processus sont gérés dans le système d'exploitation Linux.
Il ne faut donc pas confondre le fichier contenant un programme (portent souvent l'extension .exe sous windows) et le ou les processus qu'il engendre quand il est exécuté : Un programme est juste un fichier contenant une suite d'instructions (firefox.exe par exemple) alors que les processus sont des instances de ce programme ainsi que les ressources nécessaires à leur exécution (plusieurs fenêtres de firefox ouvertes en même temps).
Pour prendre une image assez classique, si une recette de cuisine correspond au code source du programme, les tâches du cuisinier en train de préparer cette recette dans sa cuisine correspondent aux processus.
La création d'un processus peut intervenir
Un processus peut créer un ou plusieurs processus à l'aide d'une commande système ("fork" sous les systèmes de type Unix). Imaginons un processus A qui crée un processus B. On dira que A est le père de B et que B est le fils de A. B peut, à son tour créer un processus C (B sera le père de C et C le fils de B). On peut modéliser ces relations père/fils par une structure arborescente.
Si un processus est créé à partir d'un autre processus, comment est créé le tout premier processus ?
Sous un système d'exploitation comme Linux, au moment du démarrage de l'ordinateur un tout premier processus (appelé processus 0 ou encore Swapper
est créé à partir de "rien" (il n'est le fils d'aucun processus). Ensuite, ce processus 0 crée un processus souvent appelé "init" ("init" est donc le fils du processus 0).
À partir de "init", les processus nécessaires au bon fonctionnement du système sont créés (par exemple les processus "crond", "inetd", "getty",...)
Puis d'autres processus sont créés à partir des fils de "init"...
Ouvrir le Simulateur terminal linux aussi apellé shell
Dans un terminal, tester l'instruction pstree -p
qui permet de visualiser l'arbre de processus. Recopier ci-dessous, l'arbre des processus :
Il est possible de visualiser les processus grâce à la commande ps -eF
.
Pour un affichage page par page, utilisez ps -eF | more
Un processus est caractérisé par un identifiant unique : son PID (Process Identifier).
Lorsqu'un processus engendre un fils, l'OS génère un nouveau numéro de processus pour le fils. Le fils connaît aussi le numéro de son père :
le PPID (Parent Process Identifier).
python
Une commande indispensable à connaître sous Linux pour inspecter les processus est la commande top
.
L'affichage se rafraîchit en temps réel contrairement à ps
qui fait un instantané.
Voici quelques option qui s'activent s'activent par des raccourcis clavier. En voici quelques uns :
top
top
.Pour tuer un processus, on lui envoie un signal de terminaison. On en utilise principalement deux :
Pour terminer proprement un processus :
vous lui enverrez donc un signal SIGTERM en tapant : la commande shell kill -15 PID
où PID désigne le numéro du processus à quitter proprement.
Si ce dernier est planté et ne réagit pas à ce signal, alors vous pouvez vous en débarasser en tapant kill -9 PID
.
kill
Les systèmes d'exploitation modernes sont capable d'exécuter plusieurs processus "en même temps". En réalité ces processus ne sont pas toujours exécutés "en même temps" mais plutôt "à tour de rôle". On parle d'exécution concurrente car les processus sont en concurrence pour obtenir l'accès au processeur chargé de les exécuter.
Sur un système multiprocesseur, il est possible d'exécuter de manière parallèle plusieurs processus, autant qu'il y a de processeurs. Mais sur un même processeur, un seul processus ne peut être exécuté à la fois.
On peut voir assez facilement cette exécution concurrente. Considérons les deux programmes Python suivants :
progA.py
progB.py
En ouvrant un Terminal, on peut lancer simultanément ces deux programmes avec la commande
Le caractère
&
qui suit une commande permet de lancer l'exécution en arrière plan et de rendre la main au terminal.
Le shell indique alors dans la console les PID des processus correspondant à l'exécution de ces deux programmes (ici 9154 et 9155) puis on constate grâce aux affichages que le système d'exploitation alloue le processeur aux deux programmes à tour de rôle
Une ressource est une entité dont a besoin un processus pour s'exécuter. Les ressources peuvent être matérielles (processeur, mémoire, périphériques d'entrée/sortie, ...) mais aussi logicielles (variables).
Les différents processus se partagent les ressources, on parle alors d'accès concurrents aux ressources. Par exemple,
C'est le système d'exploitation qui est chargé de gérer les processus et les ressources qui leur sont nécessaires, en partageant leur accès au processeur. Nous allons voir comment tout de suite !
Tous les systèmes d'exploitation "modernes" (Linux, Windows, macOS, Android, iOS...) sont capables de gérer l'exécution de plusieurs processus en même temps. Mais pour être précis, cela n'est pas en véritable "en même temps", mais plutôt un "chacun son tour".
Un système d’exploitation multitâche ré-attribue périodiquement à l’UC une tâche différente dans le but de faire progresser l’exécution de plusieurs programmes à la fois.
Voici les différents états :
Le passage de l'état "prêt" vers l'état "élu" constitue l'opération "d'élection".
Le passage de l'état élu vers l'état bloqué est l'opération de "blocage".
Pour se terminer, un processus doit obligatoirement se trouver dans l'état "élu".
On peut résumer tout cela avec le diagramme suivant :
Lorsqu'un processus est interrompu, il doit pouvoir reprendre à l'endroit même où il a été interrompu. Pour cela, le système d'exploitation conserve pour chaque processus créé une zone mémoire (appelée PCB, pour Process Control Bloc, ou bloc de contrôle du processus) dans laquelle sont stockées les informations sur le processus : son PID, son état, la valeur des registres lors de sa dernière interruption, la zone mémoire allouée par le processus lors de son exécution, les ressources utilisées par le processus (fichiers ouverts, connexions réseaux en cours d'utilisation, etc.).
Il est vraiment important de bien comprendre que le "chef d'orchestre" qui attribue aux processus leur état "élu", "bloqué" ou "prêt" est
le système d'exploitation .
On dit que le système gère l'ordonnancement des processus (tel processus sera prioritaire sur tel autre...)
Chose aussi à ne pas perdre de vu : Pour libérer une ressource, un processus doit obligatoirement être dans un état "élu".
Afin d'élire quel processus va repasser en mode "élu", l'ordonnanceur applique un algorithme prédéfini lors de la conception de l'OS.
Le choix de cet algorithme va impacter directement la réactivité du système et les usages qui pourront en être fait.
C'est un élément critique du système d'exploitation.
Sous Linux, on peut passer des consignes à l'ordonnanceur en fixant des priorités aux processus dont on est propriétaire :
Cette priorité est un nombre NI entre -20 (plus prioritaire) et +20 (moins prioritaire).
Pour gérer l'élection d'un processus,on peut agir à 2 niveaux :
nice
renice
les colonne PR et NI de la commande top
montrent le niveau de priorité de chaque processus
Le lien entre PR et NI est simple : PR = NI + 20 ce qui fait qu'une priorité PR de 0 équivaut à un niveau de priorité maximal.
Exemple : Pour baisser la priorité du process terminator
dont le PID est 21523, il suffit de taper : renice +10 21523
L'objectif de l'ordonnanceur est de choisir le processus à exécuter à l'instant
C'est le système d'exploitation qui attribue aux processus leurs états élu, prêt et bloqué. Plus précisément, c'est l'ordonnanceur (un des composants du système d'exploitation) qui réalise cette tâche appelée ordonnancement des processus.
L'objectif de l'ordonnanceur est de choisir le processus à exécuter à l'instant t (le processus élu) et déterminer le temps durant lequel le processeur lui sera alloué.
Fig. 2 - Ordonnancement des processus.
Ce choix est à faire parmi tous les processus qui sont dans l'état prêt, mais lequel sera élu ? et pour combien de temps ? Des algorithmes d'ordonnancement sont utilisés et il en existe plusieurs selon la stratégie utilisée. On en présente quelques-uns ci-dessous.
Principe : Les processus sont ordonnancés selon leur ordre d'arrivée ("premier arrivé, premier servi" en français)
Exemple : Les processus P1(53), P2(17), P3(68) et P4(24) arrivent dans cet ordre à t=0.
P1(53), P2(17), P3(68) et P4(24) signifie que P1 , P2, P3 et P4 ont besoin de respectivement 53, 17, 68 et 24 unités de temps pour s'exécuter.
Diagramme de Gantt :
Principe : Le processus dont le temps d'exécution est le plus court est ordonnancé en premier.
Exemple : P1, P2, P3 et P4 arrivent à t=0 :
Diagramme de Gantt
Principe : Le processus dont le temps d'exécution restant est le plus court parmi ceux qui restent à exécuter est ordonnancé en premier.
Exemple : P3 et P4 arrivent à t=0 ; P2 à t=20 ; P1 à t=50 :
Diagramme de Gantt :
Principe : C'est la politique du tourniquet : allocation du processeur par tranche (= quantum q) de temps.
p> Exemple : quantum q=20 et n=4 processusDiagramme de Gantt :
Dans ce cas, s'il y a unités de temps au plus
Principe : Allocation du processeur selon des priorités statiques (= numéros affectés aux processus pour toute la vie de l'application)
Exemple : priorités où la priorité la plus forte est 0 (attention, dans certains systèmes c'est l'inverse : 0 est alors la priorité la plus faible)
Diagramme de Gantt :