Gestion des processus
Cette activité traite de questions assez importantes qui ont été mises de côté jusqu'à présent :
- qu'est-ce qu'un processus par rapport à un programme ?
- comment démarre un processus ?
- comment l'ordinateur parvient-il à gérer plusieurs processus en même temps ?
- pourquoi certaines applications se figent-elles définitement parfois ?
- que viennent faire des zombis dans un cours de NSI ?
1 - Vocabulaire : Programme, processus et processeur
Programme
Un programme est un ensemble d'instructions permettant de faire réaliser certaines tâches à un système informatique. Il s'agit donc d'une implémentation en machine d'un algorithme (algorithme qui peut lui être vu comme l'idée abstraite de l'action à accomplir).
En réalité, derrière ce mot "programme" se trouve deux notions :
- Il s'agit d'une suite de bits directement compréhensible par le processeur.
- Exemple d'un ensemble de bits permettant de transférer le contenu d'une zone-mémoire dans l'un des registres de processeur :
- En base 02 :
0010 0010 0011 1001 0000 0000 0000 0000 0000 0000 0010 0000
- En base 16 :
2239 0000 0020h
en utilisant la méthode des quartets - On peut le traduire si on sait qu'il s'agit du jeu d'instructions 68000 de Motorola, on peut lire dans la notice que
001
en début d'instruction signifie qu'on veut déplacer des données en mémoire (dont on donne l'adresse) vers un registre. - La traduction mot à mot en utilisant quelques mots clés plutôt que les valeurs réelles des bits se nomme le langage d'assemblage, ou assembleur par abus de langage.
- En base 02 :
- Il s'agit des instructions fournies dans un langage de programmation.
- Ce code-source est compréhensible par un humain.
- Ce code-source n'est pas compréhensible par le processeur d'un système informatique et doit être traduit en langage machine.
- Voyons deux manières de gérer cette traduction :
- les langages compilés (comme le langage C par exemple)
- En première approximation, on peut le voir comme le fait de fournir le code-source à un compilateur qui va transformer le transformer en "code-machine". On transmet directement le "code-machine".
- Avantages : rapidité (la traduction est déjà faite en grande partie) et la personne n'a pas d'autres programmes à installer sur sa machine.
- Désavantages : le "code-machine" créé n'est compréhensible que par les systèmes d'exploitation et processeurs compatibles, compilation à faire à chaque fois qu'on veut vérifier le programme
- les langages interprétés (comme le langage Python par exemple)
- En première approximation, on peut le voir comme le fait de fournir le code-source à un interpréteur qui va transformer le code-source à la volée en code-machine. On transmet le code-source.
- Avantages : le code-source est traduit directement par l'interpréteur du système sur lequel il doit tourner et va donc être compatible (sauf si le code-source utilise certaines spécificités de l'OS par exemple). La mise au point du programme est rapide puisqu'on peut le tester rapidement sans passer par la phase compilation.
- Désavantages : c'est souvent lent (la traduction doit être faite en grande partie à la volée) et la personne doit avoir un interpréteur installé sur sa machine.
Processeur
Le processeur est composé principalement des parties suivantes :
- L'UDC (Unité de Commande) permettant de gérer X bits à la fois : la partie de la puce qui lit la prochaine tâche élémentaire à effectuer en mémoire et qui commande l'UAL pour effectuer cette tâche élémentaire.
- L'UAL (Unité Arithmétique et Logique) permettant de traiter X bits à la fois : la partie de la puce qui effectue les calculs, les déplacements en mémoire...
- Quelques registres permettent de stocker et lire très rapidement en mémoire
- Des bus permettant de transporter X bits à la fois
On nomme cela UCT (Unité Centrale de Traitement en français) ou CPU (Central Processing Unit en anglais).
Création d'un processus
Que se passe-t-il lorsqu'on veut exécuter un programme ?
Sachant que le programme n'est qu'une suite d'octets placés en mémoire de masse (disque dur, disque SSD, clé USB...), on va devoir :
- réserver une place spécifique en mémoire vive (RAM) (on parle de virtualisation de la mémoire)
- copier le code du programme en mémoire vive (RAM)
- commençer à gérer l'exécution du code du processus
Un processus est donc l'exécution concrète d'un programme par le processeur à partir d'une zone mémoire virtuelle propre à ce processus.
On dit également qu'un processus est une instance d'un programme : le programme est bien le moule permettant de générer le processus. Cette façon de voir les choses montrent bien qu'on peut lancer deux fois un même programme : on obtient en réalité deux instances, deux processus différents, disposant chacun de sa propre zone mémoire.
Les mots "tâches" et "processus" sont équivalents.
01° Qu'est-ce qui limite concrétement le nombre de processus pouvant être lancer en même temps ?
...CORRECTION...
La place en RAM.
Dès que la place est pleine, cela va énormément ralentir l'ordinateur : il est obligé de faire des copier-coller réguliers des données et des instructions entre la RAM et la mémoire de masse (qui est beaucoup plus lente).
02° Qu'est-ce qu'un système d'exploitation multitâche ?
...CORRECTION...
Un système d'exploitation qui sait faire fonctionner plusieurs processus "en même temps".
03° Que va devoir faire un système d'exploitation multitâche lorsque plusieurs processus fonctionnent "en même temps" sur un ordinateur ne disposant que d'un seul microprocesseur (un coeur) ?
...CORRECTION...
Le système d'exploitation va devoir choisir à qui offir les services du processeur.
04° Que se passe-t-il au démarrage de l'ordinateur ?
...CORRECTION...
Un premier programme bien spécifique est placé en mémoire automatiquement pour en faire le premier processus au démarrage.
Premier démarrage : le chargeur d’amorçage
Lorsqu'on démarre un système informatique, il est conçu pour générer automatiquement un premier processus en allant chercher un programme dans une zone précise de la mémoire : le chargeur d'amorçage ou bootloader en anglais.
Ce processus va alors déclencher tous un tas d'autres processus : ceux permettant le démarrage du système d'exploitation par exemple.
Les démons (daemons en anglais)
Il s'agit d'une catégorie particulière de processus : des processus qui tournent en boucle car ils surveillent spécifiquement certaines choses.
Leurs noms finissent souvent par ...d.
Exemples :
- httpd : le processus d'un serveur HTTP
- crond : le processus du planificateur de tâches Cron (pour Chrono Table) de Linux (et Unix)
Et une application ?
Une application peut être vue comme étant un ensemble de processus produisant un effet commun.
La plupart des applications réelles ne sont pas modélisables comme un seul processus : on encapsule certaines de leurs fonctions dans des processus indépendants discutant entre eux en utilisant des signaux, de la mémoire partagée, ou des tubes.
2 - Etats du processus
Voyons maintenant le cycle de vie d'un processus.
Etats d'un processus
Le programme est initialement en mémoire.
On commence par l'état initialisé : on réserve de la place en mémoire vive, on copie le code...
Le processus passe alors automatiquement à l'état PRET : il est prêt à faire exécuter sa prochaine instruction élémentaire au processeur. Mais pour l'instant, il n'y a pas accès.
Le système d'exploitation va alors élire le prochain processus pouvant accéder au processeur : l'élection.
Le processus passe à l'état ELU s'il remporte l'élection : ce sont ses instructions qui vont être traitées par le processeur.
Trois situations alors :
- Le processus n'a plus d'instructions à traiter : il passe à l'état FINI (ZOMBI). Il n'est pas encore mort, mais ça ne devrait pas tarder.
- Le processus est en attente d'une réponse d'une ressource ou d'une entrée : il passe à l'état BLOQUE.
- Le processeur a décidé de donner l'accès à un autre processus : il passe à l'état PRET.
Le processus passe à l'état BLOQUE.
Il pourra revenir à l'état PRET lorsque le système aura reçu la ressource qu'il attend pour ce processus.
05° Quels sont les états pendant lesquels la mémoire vive réserve de la place au processeur ?
...CORRECTION...
Dans les 5 états.
Dans le premier état, le processus vient de gagner sa place mémoire.
Dans les 3 blancs (PRET - ELU - BLOQUE), il est en cours de traitement.
Dans le dernier (FINI/ZOMBIE), il n'est pas encore mort. La mémoire est libérée en partie mais pas entièrement : nous allons voir que le processus qui l'a créé va venir récolter quelques dernières informations (comme une réponse par exemple) afin de le supprimer définitivement.
Gestionnaire d'interruption
Si on se limitait à cela, un processus n'aura pas son mot à dire en étant à l'état BLOQUE ou PRET. Il devrait tranquillement attendre son tour même si un événement important survenait pour lui.
Imaginons qu'on veuille émettre un bip lorsqu'on tape sur une touche. Si le processus pouvant faire cela est en PRET ou BLOQUE, il ne pourrait rien faire tant que le processeur ne lui permette pas de continuer son exécution. D'ailleurs, le processus ne serait même pas au courant de l'appui sur la touche.
Les systèmes d'exploitation intégrent donc un système de gestion d'interruption : un processus peut signaler qu'il doit effectuer des actions si un certain événement apparaît, on peut surveiller qu'une ressource finit par répondre à un appel provoqué par le processus...
Le système d'exploitation peut alors interrompre le fonctionnement du processeur et provoquer une nouvelle élection.
L'une des interruptions est d'ailleurs l'interruption d'horloge qui permet de provoquer périodiquement une nouvelle élection.
3 - Linux
Pour commencer vous allez faire un petit TP pour vous familiariser avec LINUX
06° Lancer le TP en cliquant sur le lien ci-contre. TP - Ligne de commande
Ne pas faire la dernière partie - TP : Une console en ligne
Commande ps (process status) - introduction
La commande ps permet d'obtenir la liste des processus actifs dans un terminal Linux (ici en utilisant la "simulation" de terminal, l'application graphique bash en réalité).
rv@rv-HP2:~$ ps
PID TTY TIME CMD
17255 pts/1 00:00:00 bash
18060 pts/1 00:00:00 ps
Cette commande donne plusieurs informations sur les processus actifs :
- PID : le numéro d'identification du processus dans le système d'exploitation. PID veut dire Process IDentifier. Sous Linux, c'est un entier naturel encodé sous 32 bits.
- TTY : le terminal ou son équivalent application graphique qui "contrôle" le processus. Si le processus est un démon non rattaché à un terminal, vous verriez "?".
- TIME : fournit le temps d'utilisation du CPU par ce processus. Attention, il s'agit bien du temps d'utilisation du processus : si on active Blender via le bash, le temps d'utilisation sera attribué à Blender : le Bash n'a servi qu'à lancer le processus de Blender.
- CMD : la commande qui a engendré la création du processus.
La commande ps est similaire à la commande tasklist de Microsoft Windows. Dans Windows PowerShell, ps est un alias pré-défini de la commande Get-Process qui a globalement la même fonction.
07° Lancer le Weblinux.WEBLINUX UNIVERSITE REUNION
Puis entrer la commande ps
:~$ ps
■
Regarder ce que vous obtenez.
...CORRECTION...
:~$ ps
PID TTY TIME CMD
58 ttyS0 15049-12:58:15 bash
68 ttyS0 15049-12:58:15 ps
Il faut savoir qu'il y a un lien entre deux programmes : la fermeture du bash provoque la fermeture d'un programme donné.
On peut donc dire que le bash est le père de ce Programme.
Nous allons retrouver les Arbres !
Observer l'arbre des processus avec pstree
Voici un exemple de hierarchie qu'on peut observer sur les processus qui lance d'autres processus :
On peut ouvrir un nouveau terminal et utiliser ceci : On utilise une console linux qui lance "Blender"
rv@rv-HP2:~$ ps
PID TTY TIME CMD
20552 pts/1 00:00:00 bash
20562 pts/1 00:00:00 ps
rv@rv-HP2:~$ blender &
[1] 20563
rv@rv-HP2:~$ pstree
systemd─┬─ModemManager───2*[{ModemManager}]
├─NetworkManager───2*[{NetworkManager}]
├─accounts-daemon───2*[{accounts-daemon}]
├─acpid
├─avahi-daemon───avahi-daemon
├─bluetoothd
├─colord───2*[{colord}]
├─cron
├─cups-browsed───2*[{cups-browsed}]
├─cupsd
├─dbus-daemon
├─dnsmasq───dnsmasq
├─fwupd───4*[{fwupd}]
├─gdm3─┬─gdm-session-wor─┬─gdm-x-session─┬─Xorg───20*[{Xorg}]
│ │ │ ├─gnome-session-b─┬─ssh-agent
│ │ │ │ └─2*[{gnome-+
│ │ │ └─2*[{gdm-x-session}]
│ │ └─2*[{gdm-session-wor}]
│ └─2*[{gdm3}]
├─gnome-keyring-d─┬─ssh-agent
│ └─3*[{gnome-keyring-d}]
├─irqbalance───{irqbalance}
├─2*[kerneloops]
├─libvirtd───16*[{libvirtd}]
├─networkd-dispat
├─polkitd───2*[{polkitd}]
├─rsyslogd───3*[{rsyslogd}]
├─rtkit-daemon───2*[{rtkit-daemon}]
├─snapd───19*[{snapd}]
├─switcheroo-cont───2*[{switcheroo-cont}]
├─systemd─┬─(sd-pam)
│ ├─at-spi-bus-laun─┬─dbus-daemon
│ │ └─3*[{at-spi-bus-laun}]
│ ├─at-spi2-registr───2*[{at-spi2-registr}]
│ ├─atom─┬─atom───atom─┬─atom
│ │ │ └─4*[{atom}]
│ │ ├─atom───atom
│ │ ├─atom───4*[{atom}]
│ │ ├─atom───18*[{atom}]
│ │ ├─atom───10*[{atom}]
│ │ └─33*[{atom}]
│ ├─dbus-daemon
│ ├─dconf-service───2*[{dconf-service}]
│ ├─2*[evince───5*[{evince}]]
│ ├─evinced───2*[{evinced}]
│ ├─evolution-addre───5*[{evolution-addre}]
│ ├─evolution-calen───8*[{evolution-calen}]
│ ├─evolution-sourc───3*[{evolution-sourc}]
│ ├─firefox─┬─Privileged Cont───24*[{Privileged Cont}]
│ │ ├─RDD Process───2*[{RDD Process}]
│ │ ├─3*[Web Content───28*[{Web Content}]]
│ │ ├─2*[Web Content───24*[{Web Content}]]
│ │ ├─Web Content───29*[{Web Content}]
│ │ ├─2*[Web Content───32*[{Web Content}]]
│ │ ├─WebExtensions───24*[{WebExtensions}]
│ │ └─106*[{firefox}]
│ ├─gimp-2.10─┬─script-fu───2*[{script-fu}]
│ │ └─7*[{gimp-2.10}]
│ ├─gjs───6*[{gjs}]
│ ├─gnome-session-b─┬─evolution-alarm───5*[{evolution-alarm}]
│ │ ├─gsd-disk-utilit───2*[{gsd-disk-utilit}]
│ │ ├─solaar───3*[{solaar}]
│ │ ├─update-notifier───3*[{update-notifier}]
│ │ └─3*[{gnome-session-b}]
│ ├─gnome-session-c───{gnome-session-c}
│ ├─gnome-shell─┬─evince───4*[{evince}]
│ │ ├─ibus-daemon─┬─ibus-dconf───3*[{ibus-dconf}]
│ │ │ ├─ibus-engine-sim───2*[{ibus-engi+
│ │ │ ├─ibus-extension-───3*[{ibus-exte+
│ │ │ └─2*[{ibus-daemon}]
│ │ ├─notepadqq-bin───7*[{notepadqq-bin}]
│ │ ├─oosplash─┬─soffice.bin───5*[{soffice.bin}]
│ │ │ └─{oosplash}
│ │ └─12*[{gnome-shell}]
│ ├─gnome-shell-cal───5*[{gnome-shell-cal}]
│ ├─gnome-terminal-─┬─bash───python───python───7*[{python}]
│ │ ├─bash─┬─blender───20*[{blender}]
│ │ │ └─pstree
│ │ └─4*[{gnome-terminal-}]
│ ├─goa-daemon───3*[{goa-daemon}]
│ ├─goa-identity-se───2*[{goa-identity-se}]
│ ├─gsd-a11y-settin───3*[{gsd-a11y-settin}]
│ ├─gsd-color───3*[{gsd-color}]
│ ├─gsd-datetime───3*[{gsd-datetime}]
│ ├─gsd-housekeepin───3*[{gsd-housekeepin}]
│ ├─gsd-keyboard───3*[{gsd-keyboard}]
│ ├─gsd-media-keys───3*[{gsd-media-keys}]
│ ├─gsd-power───3*[{gsd-power}]
│ ├─gsd-print-notif───2*[{gsd-print-notif}]
│ ├─gsd-printer───2*[{gsd-printer}]
│ ├─gsd-rfkill───2*[{gsd-rfkill}]
│ ├─gsd-screensaver───2*[{gsd-screensaver}]
│ ├─gsd-sharing───3*[{gsd-sharing}]
│ ├─gsd-smartcard───4*[{gsd-smartcard}]
│ ├─gsd-sound───3*[{gsd-sound}]
│ ├─gsd-wacom───2*[{gsd-wacom}]
│ ├─gsd-xsettings───3*[{gsd-xsettings}]
│ ├─gvfs-afc-volume───3*[{gvfs-afc-volume}]
│ ├─gvfs-goa-volume───2*[{gvfs-goa-volume}]
│ ├─gvfs-gphoto2-vo───2*[{gvfs-gphoto2-vo}]
│ ├─gvfs-mtp-volume───2*[{gvfs-mtp-volume}]
│ ├─gvfs-udisks2-vo───3*[{gvfs-udisks2-vo}]
│ ├─gvfsd─┬─gvfsd-dnssd───2*[{gvfsd-dnssd}]
│ │ ├─gvfsd-network───3*[{gvfsd-network}]
│ │ ├─gvfsd-smb-brows───3*[{gvfsd-smb-brows}]
│ │ ├─gvfsd-trash───2*[{gvfsd-trash}]
│ │ └─2*[{gvfsd}]
│ ├─gvfsd-fuse───5*[{gvfsd-fuse}]
│ ├─gvfsd-metadata───2*[{gvfsd-metadata}]
│ ├─ibus-portal───2*[{ibus-portal}]
│ ├─ibus-x11───2*[{ibus-x11}]
│ ├─nautilus───5*[{nautilus}]
│ ├─pulseaudio───3*[{pulseaudio}]
│ ├─sd_dummy───2*[{sd_dummy}]
│ ├─sd_espeak-ng───4*[{sd_espeak-ng}]
│ ├─snap-store───4*[{snap-store}]
│ ├─speech-dispatch───2*[{speech-dispatch}]
│ ├─tracker-miner-f───4*[{tracker-miner-f}]
│ ├─xdg-document-po─┬─fusermount
│ │ └─5*[{xdg-document-po}]
│ └─xdg-permission-───2*[{xdg-permission-}]
├─systemd-journal
├─systemd-logind
├─systemd-machine
├─systemd-resolve
├─systemd-timesyn───{systemd-timesyn}
├─systemd-udevd
├─thermald───{thermald}
├─udisksd───4*[{udisksd}]
├─unattended-upgr───{unattended-upgr}
├─upowerd───2*[{upowerd}]
├─whoopsie───2*[{whoopsie}]
└─wpa_supplicant
rv@rv-HP2:~$
Impressionnant non ?
On peut aussi faire la même chose mais en affichant en plus les PID (résultat tronqué car trop long...).
rv@rv-HP2:~$ pstree -p
systemd(1)─┬─ModemManager(1064)─┬─{ModemManager}(1135)
│ └─{ModemManager}(1139)
├─NetworkManager(922)─┬─{NetworkManager}(1038)
│ └─{NetworkManager}(1063)
├─accounts-daemon(975)─┬─{accounts-daemon}(1009)
│ └─{accounts-daemon}(1034)
├─systemd(1335)─┬─(sd-pam)(1336)
│ ├─gnome-terminal-(3791)─┬─bash(3799)───python(3808)─+++
│ │ ├─bash(20552)─┬─blender(2056+
│ │ │ └─pstree(20927+
rv@rv-HP2:~$
8° Qui est le père (nom et ID) du processus basé sur pstree ? A-t-il d'autres enfants (noms et PID éventuels) ?
Qui est le processus-racine (celui qui n'a pas de parent) ? Quel est le PID de ce processus si particulier ?
...CORRECTION...
Voici l'Arbre fortement simplifié :
rv@rv-HP2:~$ pstree -p
systemd(1)─┬─systemd(1335)─┬─(sd-pam)(1336)
│ ├─gnome-terminal-(3791)─┬─bash(3799)───python(3808)─+++
│ │ ├─bash(20552)─┬─blender(2056+
│ │ │ └─pstree(20927+
On voit que le processus-parent de pstree(PID 20927) est une instance de bash, l'instance bash(PID 20552).
Le processus bash(PID 20552) a un autre enfant : blender(PID 2056).
On remarque enfin que TOUS les processus sont des descendants d'un seul processus :
Le processus systemd dont le PID est 1.
Il finit en d car c'est un processus daemon/démon : il fonctionne en boucle.
9° A votre avis, que va-t-il se passer si on tape ceci ?
rv@rv-HP2:~$ kill 3791
...CORRECTION...
Nous allons demander de tuer ce processus ce qui va provoquer la mort de tous ses descendants également.
rv@rv-HP2:~$ kill 3791
Comme toutes les commandes, pstree possède de multiples options. On peut par exemple afficher directement les parents d'un processus dont on connait le PID :
rv@rv-HP2:~$ pstree -s 20563
systemd───systemd───gnome-terminal-───bash───blender───20*[{blender}]
Commande ps (process status) - états des processus
La commande ps permet d'obtenir la liste des processus actifs dans un terminal Linux.
Vous devez savoir :
- que les processus sont identifiés par un identifiant nommé PID.
- Un processus est toujours l'enfant d'un autre processus, excepté pour les deux premiers d'entre eux qui servent de racine à leur propre arbre :
- PID 1 : la racine init dans l'espace utilisateur.
- PID 2 : la racine kthreadd dans l'espace noyau
- A partir de ce moment, on ne peut créer un nouveau processus qu'en utilisant un appel système fork() qui va permettre de dupliquer le processus en cours, notamment toutes celles de l'environnement du processus parent. En modifiant ensuite ce processus pour rajouter le code du nouveau programme voulu, on peut créer un nouveau processus dépendant du processus père.
- Chaque processus connait le PID de son parent. On le nomme PPID, comme Parent PID
- Chaque processus connait le PID de ses enfants
- Tuer un processus (avec kill PID ou juste via l'interface graphique) provoque la disparition également de tous les descendants du processus parent.
La commande ps possède en réalité de très nombreuses options. On peut ainsi si on le veut visualiser le PID du processus ainsi que le PID de processus parent (celui qui a lancé ce processus).
Pour obtenir de la description de la commande :
rv@rv-HP2:~$ man ps
Pour obtenir une liste avec pas mal d'informations :
rv@rv-HP2:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 169288 12032 ? Ss 08:16 0:03 /sbin/init sp
root 2 0.0 0.0 0 0 ? S 08:16 0:00 [kthreadd]
systemd+ 809 0.0 0.1 25308 13280 ? Ss 08:16 0:05 /lib/systemd/
rv 1335 0.0 0.1 20448 10808 ? Ss 08:17 0:03 /lib/systemd/
rv 22334 0.7 0.0 15344 5956 pts/1 Ss 18:11 0:00 bash
rv 22342 0.0 0.0 16928 4336 pts/1 R+ 18:11 0:00 ps aux
- USER : l'utilisateur ayant généré le processus
- PID : le numéro d'identification du processus
- %CPU : % d'utilisation du CPU par ce processus
- %MEM : % d'utilisation de la mémoire par ce processus
- VSZ : donne l'utilisation des bibliotheques partagées et la memoire utilisé pour son fonctionnement
- RSS : mémoire physique utilisée en kilobytes
- TTY : le terminal contrôlant le processus
- STAT : affiche l'état actuel du processus (voir plus bas)
- START : heure à laquelle le procédure à démarrer
- TIME : le temps d'utilisation du CPU par ce processus.
- CMD : la commande qui a engendré la création du processus.
Cette commande donne plusieurs informations sur les processus actifs :
- PID : le numéro d'identification du processus dans le système d'exploitation. PID veut dire Process IDentifier. Sous Linux, c'est un entier naturel encodé sous 32 bits.
- TTY : le terminal ou son équivalent application graphique qui "contrôle" le processus. Si le processus est un démon non rattaché à un terminal, vous verriez "?".
- TIME : fournit le temps d'utilisation du CPU par ce processus. Attention, il s'agit bien du temps d'utilisation du processus : si on active Blender via le bash, le temps d'utilisation sera attribué à Blender : le Bash n'a servi qu'à lancer le processus de Blender.
- CMD : la commande qui a engendré la création du processus.
L'état des processus (STAT, comme Status) est ce qui nous intéresse ici :
Les status possibles
- R (Running et Runnable) : en cours d'exécution. Nous verrons que cela correspond aux états PRET (Runnable) ou ELU (Running) de la partie 2.
- S (Sleeping) : endormi. Cela correspond à l'état BLOQUE de la partie 2.
- D (Device) : en attente d'une ressource (généralement d'entrée/sortie) (le processus ne peut pas être interrompu). Cela correspond à l'état BLOQUE de la partie 2.
- T (sTopped) : terminé et va transmettre sa réponse à son parent. On libère une partie de la mémoire mais on garde encore des informations sur son état final.
- Z (Zombie) : processus terminé ayant répondu mais dont le parent n'a pas encore eu le temps de totalement finir la destruction.
- X (Dead) : processus terminé et détruit (vous ne devriez jamais voir de X dans votre liste).
Les trois états terminaux FINI :
On peut trouver une deuxième lettre derrière l'état : il s'agit de la priorité du processus :
- < : Priorité haute
- + : Processus au premier plan
- s : Leader de session
- l : multi-theads
- N : Priorité basse
- L : ressources verrouillées en mémoire
10° Un processus doit disparaître. Il passe en STAT Z. Qui peut le faire passer à l'état STAT X ?
...CORRECTION...
Son parent direct.
On peut configurer ps pour lui faire afficher ce qu'on désire bien entendu.
rv@rv-HP2:~$ ps -ef -o "user pid ppid stat start command"
USER PID PPID STAT STARTED COMMAND
rv 23006 3791 Ss+ 18:36:54 bash GJS_DEBUG_TOPICS=JS ERROR;JS LOG SSH_AUTH_SOCK=/run/use
rv 22334 3791 Ss 18:11:15 bash GJS_DEBUG_TOPICS=JS ERROR;JS LOG SSH_AUTH_SOCK=/run/use
rv 22990 22334 T 18:36:28 \_ python SHELL=/bin/bash SESSION_MANAGER=local/rv-HP2:@/tm
rv 23435 22334 SLl 18:52:17 \_ blender SHELL=/bin/bash SESSION_MANAGER=local/rv-HP2:@/t
rv 23498 22334 SLl 18:54:19 \_ blender SHELL=/bin/bash SESSION_MANAGER=local/rv-HP2:@/t
rv 23672 22334 R+ 19:02:00 \_ ps -ef -o user pid ppid stat start command SHELL=/bin/ba
rv 3799 3791 Ss 08:23:36 bash GJS_DEBUG_TOPICS=JS ERROR;JS LOG SSH_AUTH_SOCK=/run/use
rv 3808 3799 S+ 08:23:53 \_ python manage.py runserver SHELL=/bin/bash SESSION_MANAG
rv 9087 3808 Sl+ 11:27:21 \_ /home/rv/Envs/siteifa3/bin/python manage.py runserve
rv 1498 1144 Ssl+ 08:17:22 /usr/libexec/gdm-x-session --run-script env GNOME_SHELL_SESS
rv 1502 1498 Sl+ 08:17:22 \_ /usr/lib/xorg/Xorg vt2 -displayfd 3 -auth /run/user/1000
rv 1652 1498 Sl+ 08:17:43 \_ /usr/libexec/gnome-session-binary --systemd --session=ub
On peut filtrer en cherchant les instances d'un programme spécifique.
Un exemple où j'ai ouvert blender deux fois de suite pour avoir deux versions du programme à l'écran.
rv@rv-HP2:~$ blender &
[2] 23435
rv@rv-HP2:~$ blender &
[3] 23498
rv@rv-HP2:~$ ps -fC blender
UID PID PPID C STIME TTY TIME CMD
rv 23435 22334 6 18:52 pts/1 00:00:08 blender
rv 23498 22334 45 18:54 pts/1 00:00:02 blender
11° Les deux instances de Blender ont-elles été créées à partir du même endroit ?
...CORRECTION...
Oui car leur PPID est le même : ils ont le même parent.
4 - Ordonnanceur du système d'exploitation
Maintenant que nous avons vu comment nous pouvions faire patienter les processus, nous allons voir comment le système d'exploitation parvient à choisir le prochain processus à qui il va permettre d'accéder aux services du processeur.
Principe des alternances de processus
Le système d'exploitation peut interrompre le travail du processeur et demander une nouvelle élection lorsqu'un événement particulier intervient. Par exemple :
- Une interruption d'horloge : le processeur travaille depuis la bonne durée prédéfinie avec un même processus, il est temps de passer la main.
- Une interruption liée à un événement : l'utilisateur a réalisé une action, une ressource réponds à une sollicitation...
A chaque fois que le système d'exploitation l'exige, on fait une nouvelle élection.
- On choisit le nouveau processus qui pourra profiter du processeur.
- On sauvegarde l'état des registres en cours lié du processus actuel (pour pouvoir les récupérer cet état la prochaine fois que le processus prend la main)
- On restaure l'état des registres pour le processeur qui a gagné l'élection
- On laisse le processeur et ce processus travailler ensemble.
L'ordonnancement réel n'est pas une tâche facile.
Voyons quelques façons basiques et naïves de faire cela.
12° Imaginons trois processus.
- Le premier R va demander 12 opérations basiques dès le départ.
- Le deuxième B va demander 6 opérations basiques à partir du temps 3.
- Le troisième V va demander 4 opération basiques à partir du temps 6.
■■■■■■■■■■■■
■■■■■■
■■■■
On décide de partir d'un simple principe d'alternance stricte entre tous les processus qui le demande, une FILE d'attente dont on sort et rentre régulièrement :
- on laisse le processus ELU réaliser son temps d'horloge (une instruction ici pour simplifier)
- on le transfère en PRET
- on le sort de sa FILE pour le replacer à l'entrée de sa FILE
Cela va donc créer une alternance entre les processus.
Fournir la liste successive des instructions accomplies en considérant que le temps d'horloge ne permet l'exécution que d'une instruction élémentaire.
...CORRECTION...
■■■■■ ■■■■■ ■■■■■ ■■■■■ ■■
Temps 1 : Rouge est PRET.
La File ne contient que ■ donc on sort ■ qu'on replace à l'entrée.
Temps 2 : La File ne contient que ■ donc on sort ■ qu'on replace à l'entrée.
Temps 3 : Bleu est PRET.
La File devient ■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 4 : La File est ■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 5 : La File est ■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 6 : VERT est PRET.
La File devient ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 7 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 8 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 9 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 10 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 11 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 12 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 13 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 14 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 15 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 16 : ■→■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 17 : ■→■→■ donc on sort ■ et le processus vert passe en état ZOMBIE/FINI.
Temps 18 : ■→■ donc on sort ■ et le processus bleu passe en état ZOMBIE/FINI.
Pour la suite, il ne reste que les instructions du processus rouge à réaliser.
Cet algorithme est nommé Tourniquet ou Round-robin (RR).
Il s'agit d'un algorithme préemptif (on peut faire passer un processus de ELU à PRET)
Priorité
En réalité, on associe des priorités aux processus.
C'est une valeur allant de -20 (petite priorité) à 20 (grande priorité).
On peut alors appliquer l'algorithme du Tourniquet mais en créant plusieurs files d'attente, une par priorité.
On fait donc d'abord sortir les processus de priorité 20 et on passe aux 19 uniquement une fois que les 20 n'ont pas de demande.
13° Imaginons trois processus.
- Le premier R va demander 12 opérations basiques dès le départ.
- Le deuxième B va demander 6 opérations basiques à partir du temps 3.
- Le troisième V va demander 4 opération basiques à partir du temps 6.
■■■■■■■■■■■■ avec une priorité 10.
■■■■■■ avec une priorité 0.
■■■■ avec une priorité 20.
Fournir la liste successive des instructions accomplies en considérant que le temps d'horloge ne permet l'exécution que d'une instruction élémentaire.
...CORRECTION...
On va créer trois Files d'attente : une pour les processus de priorité 10, une pour la priorité 0 et une autre pour la priorité 20. Comme nous n'avons qu'un processus par File, nous allons juste mémoriser leur présence.
■■■■■ ■■■■■ ■■■■■ ■■■■■ ■■
Temps 1 : Rouge est PRET. La File 10 devient ■.
Seule la File 10 n'est pas vide, on sort ■ qu'on replace à l'entrée.
Temps 2 : Rien de neuf.
Seule la file 10 n'est pas vide donc on sort ■ qu'on replace à l'entrée.
Temps 3 : Bleu est PRET. La File 0 devient ■
On choisit la File 10 donc on sort ■ qu'on replace à l'entrée.
Temps 4 : Rien de neuf.
On prend la File 10 donc on sort ■ qu'on replace à l'entrée.
Temps 5 : Rien de neuf.
On prend la File 10 donc on sort ■ qu'on replace à l'entrée.
Temps 6 : VERT est PRET. La File 20 devient ■.
On prend la File 20 donc on sort ■ qu'on replace à l'entrée.
Temps 7 : Rien de neuf.
On prend la File 20 donc on sort ■ qu'on replace à l'entrée.
Temps 8 : Rien de neuf.
On prend la File 20 donc on sort ■ qu'on replace à l'entrée.
Temps 9 : Rien de neuf.
On prend la File 20 donc on sort ■ et on sort le processus de la File 20 car il a fini de travailler. La File 20 est donc vide.
Temps 10 à 15 : Il n'y a plus que la File 10 et la File 0.
On prend la File 10 donc on sort ■ et on le replace à l'entrée.
Temps 16 : Il n'y a plus que la File 10 et la File 0.
On prend la File 10 donc on sort ■ et on sort le processus de la File 10 car il a fini de travailler. La File 10 est donc vide.
Temps 17+ : Il ne reste que la File 0 qui ne soit pas vide.
On prend la File 0 donc on sort ■ et on le replace à l'entrée.
Il reste à faire cela jusqu'à la fin.
13-bis° Même situation SAUF que les processus ROUGE et BLEU ont tous les deux une priorité de 10.
...CORRECTION...
On va créer deux Files d'attente : une pour les processus de priorité 10 (qui pourra contenir Rouge et Bleu) et une autre pour la priorité 20 (avec juste Vert).
■■■■■ ■■■■■ ■■■■■ ■■■■■ ■■
Temps 1 : Rouge est PRET.
La File 10 ne contient que ■ donc on sort ■ qu'on replace à l'entrée.
Temps 2 : La File 10 ne contient que ■ donc on sort ■ qu'on replace à l'entrée.
Temps 3 : Bleu est PRET.
La File 10 devient ■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 4 : La File 10 est ■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 5 : La File 10 est ■→■ donc on sort ■ qu'on replace à l'entrée.
Temps 6 : VERT est PRET.
La File 20 devient ■ et la File 10 reste ■→■
donc on sort ■ qu'on replace à l'entrée de sa File 20.
Temps 7 : Rien de neuf.
La File 20 est ■ et la File 10 reste ■→■
donc on sort ■ qu'on replace à l'entrée de sa File 20.
Temps 8 : Rien de neuf.
La File 20 est ■ et la File 10 reste ■→■
donc on sort ■ qu'on replace à l'entrée de sa File 20.
Temps 9 : Rien de neuf.
La File 20 est ■ et la File 10 reste ■→■
donc on sort ■ mais ne le replace pas à l'entrée : le processus est fini.
Temps 10 : La File 10 est ■→■
donc on sort ■ qu'on replace à l'entrée de la File 10.
Temps 11 : La File 10 est ■→■
donc on sort ■ qu'on replace à l'entrée de la File 10.
Temps 12 : La File 10 est ■→■
donc on sort ■ qu'on replace à l'entrée de la File 10.
Temps 13 : La File 10 est ■→■
donc on sort ■ qu'on replace à l'entrée de la File 10.
Temps 14 : La File 10 est ■→■
donc on sort ■ qu'on replace à l'entrée de la File 10.
Temps 15 : La File 10 est ■→■
donc on sort ■ qu'on replace à l'entrée de la File 10.
Temps 16 : La File 10 est ■→■
donc on sort ■ qu'on replace à l'entrée de la File 10.
Temps 17 : La File 10 est ■→■
donc on sort ■ qu'on replace à l'entrée de la File 10.
Temps 18 : La File 10 est ■→■
donc on sort ■ sans le remettre à l'entrée : il ne reste que le processus ROUGE dans la File 10.
Temps 19+ : La File 10 est ■
donc on sort ■ qu'on replace à l'entrée de la File 10, jusqu'à finir le processus.
Evidemment ici, nous avons simplifié à l'extrême puisqu'on vous demande de le faire à la main.
Mais on pourrait également faire varier les priorités de façon dynamique :
- L'augmenter pour ceux qui n'utilisent jamais le temps CPU à fond car ils interagissent beaucoup avec la mémoire ou les entrées/sorties
- La baisser pour ceux qui utilisent toujours le temps CPU à fond...
Autre simplification : le processus ne relâche jamais seul le processeur. On ne simule donc pas du tout les demandes d'accès au disque dur ect...
14° Après le tourniquet, voyons l'algorithme nommé FIFO qui intégre également une File. La différence vient du fait que le processus reste à l'avant de sa File tant qu'il n'est pas terminé : on ne le replace par à l'entrée de sa File lorsqu'on le place en BLOQUE ou PRET. Il est donc interrompu lorsqu'un processus plus prioritaire est dans une File plus prioritaire. MAis attention : on ne le sort pas pour autant de sa File. Nous ne sommes pas en Tourniquet.
Imaginons trois processus.
- Le premier R va demander 12 opérations basiques dès le départ.
- Le deuxième B va demander 6 opérations basiques à partir du temps 3.
- Le troisième V va demander 4 opération basiques à partir du temps 6.
■■■■■■■■■■■■ avec une priorité 10.
■■■■■■ avec une priorité 10.
■■■■ avec une priorité 20.
Utiliser l'algorithme avec gestion des priorités.
Fournir la liste successive des instructions accomplies sachant que le temps d'horloge permet l'exécution d'une instruction élémentaire.
...CORRECTION...
On va créer deux Files d'attente : une pour les processus de priorité 10 (qui pourra contenir Rouge et Bleu) et une autre pour la priorité 20 (avec juste Vert).
■■■■■ ■■■■■ ■■■■■ ■■■■■ ■■
Temps 1 : Rouge est PRET.
La File 10 ne contient que ■ donc on exécute ■.
Temps 2 : Rien de nouveau donc on exécute ■.
Temps 3 : Bleu est PRET.
La File 10 devient ■→■ donc on exécute ■.
Temps 4-5 : Rien de neuf. On exécute ■.
Temps 6 : VERT est PRET.
La File 20 devient ■ et la File 10 reste ■→■
donc on exécute ■.
Temps 7-8 : Rien de neuf. On exécute ■.
Temps 9 : Rien de neuf. On exécute ■ mais on le sort de sa File puisqu'il est terminé.
Temps 10 : Il ne reste que la File du 10 : ■→■
On exécute ■.
Temps 11-15 : Rien de neuf. On exécute ■.
Temps 16 : Rien de neuf. On exécute ■ et on le sort de sa File puisqu'il est terminé.
Temps 17+: Il ne reste que BLEU dans la File : ■
On exécute ■, jusqu'à le finir.
Temps réel
Pour les applications Temps réel, on voit bien que cela peut poser problème : rien ne peut garantir qu'on redonne immédiatement la main au bon processus si plusieurs processus on la même priorité.
Il faut alors se tourner vers des OS plus orientés temps réel, notamment des noyaux contrôlant un noyau Linux : ils peuvent alors contrôler finement les processus nécessitant du temps réel mais laisser les autres avec une gestion Linux classique.
5 - Interblocage (deadlock)
Un interblocage est une situation assez commune dans la vie de tous les jours, notamment sur un carrefour avec priorité à droite : c'est une situation où personne ne peut plus agir à cause du comportement des autres protagonistes.
En Informatique, cette situation peut se produire si plusieurs processus se bloquent les uns les autres. Comment alors que nous avons vu que l'Ordonnanceur parvenait à alterner ?
Principalement à cause des accès aux ressources (écriture sur un fichier, accès à un périphérique n'autorisant pas les utilisateurs multiples...)
15° Imaginons deux processus 1 et 2 qui pourront exécuter leurs instructions à tour de rôle, une fois le processus 1, puis le 2....
La ressource A contient "4" initialement et la ressource B contient "2".
Actions du processus 1
- Prendre le contrôle exclusif de la ressource A
- Prendre le contrôle exclusif de la ressource B
- Rajouter "2" à la fin de la ressource A
- Rajouter le contenu de la ressource A dans la ressource B
Actions du processus 2
- Prendre le contrôle exclusif de la ressource A
- Prendre le contrôle exclusif de la ressource B
- Rajouter "8" à la fin de la ressource B
- Rajouter le contenu de la ressource B dans la ressource A
On commence par exemple avec la première instruction du processus 1 : il prend le contrôle de la ressource A.
Expliquer si cette situation mènera à un interblocage, ou pas.
Donner l'ordre des instructions qui pourront s'effectuer jusqu'au blocage ou jusqu'à la fin du déroulement des processus.
...CORRECTION...
16° Même question, seules les instructions changent.
La ressource A contient "4" initialement et la ressource B contient "2".
Actions du processus 1
- Prendre le contrôle exclusif de la ressource B
- Prendre le contrôle exclusif de la ressource A
- Rajouter "2" à la fin de la ressource A
- Rajouter le contenu de la ressource A à la fin de la ressource B
Actions du processus 2
- Prendre le contrôle exclusif de la ressource A
- Prendre le contrôle exclusif de la ressource B
- Rajouter "8" à la fin de la ressource B
- Rajouter le contenu de la ressource B à la fin de la ressource A
Expliquer si cette situation est un interblocage, ou pas.
Donner l'ordre des instructions qui pourront s'effectuer jusqu'au blocage ou jusqu'à la fin du déroulement des processus.
...CORRECTION...
L'interblocage en Informatique peut intervenir dans les cas de demandes circulaires : des ressources aux accès exclusifs sont détenues par des processus différents qui ne peuvent continuer leurs déroulement qu'en accédant à une nouvelle ressource à laquelle ils n'ont pas accès pour le moment. En conséquence, ils attendent tous...
Cette situation peut survenir en programmation concurrente sous 4 conditions :
- Au moins une des ressources en accès exclusif.
- Un processus détenant déjà une ressource aura besoin d'un autre ressource (détenue par un autre processus)
- Seul le détenteur d'une ressource peut la libérer.
- Attente circulaire : Chaque processus attend une ressource détenue par un autre processus.
6 - FAQ
tty, pty et pts, c'est quoi ça ?
Le sigle tty désigne un vrai terminal de commande, en texte et implémenté directement dans le système.
Le sigle pty désigne un pseudo-terminal de commande, une émulation à travers un autre programme comme ssh pour une connexion à distance ou bash pour un "terminal" à l'intérieur d'une application graphque.
Le sigle pts désigne un pseudo-terminal slave, une partie d'un pty.
Processus et Thread, c'est pareil ?
Non, un processus est bien une instance d'un programme qui sa propre zone mémoire virtuelle.
Par contre, un processus peut faire tourner à tour de rôle plusieurs petits processus qui partagent sa propre zone mémoire virtuelle. On nomme ces "processus légers" des Threads. Les Threads ne sont donc pas des processus autonomes mais font partie d'un processus.
Activité publiée le 26 05 2021
Dernière modification : 26 05 2021
Auteur : Andjekel
Source : ows. h.