Chapitre 2: Gestion des processus par un système d'exploitation


Programme Officiel
Contenus Capacités attendues Commentaires
Gestion des processus et des ressources par un système d'exploitation.

Décrire la création d'un processus, l'ordonnancement de plusieurs processus par le système.

Mettre en évidence le risque de l'interblocage (deadlock).

À l'aide d'outils standard, il s'agit d'observer les processus actifs ou en attente sur une machine. Une présentation débranchée de l'interblocage peut être proposée.
Lien vers le programme complet

Comme nous l'avons vu en première, le système d'exploitation(Linux, Windows, MacOs...) est un programme particulier situé entre le matériel et les applications qui a pour de rôle de coordonner l'ensemble des tâches qui sont exécutées par l'ordinateur. Cette année, nous allons voir comment le système d'exploitation charge les programmes dans la mémoire de masse et lance leur exécution en leur créant des processus afin de pouvoir les gérer lors de leur exécution.

Différence entre programme et processus

Programme

Un programme est statique: c'est un fichier contenant une suite d'instructions qui lorsqu'elles sont exécutées modifient l'état du processeur et de la mémoire afin de réaliser une tâche donnée.

Un même programme peut-être exécuté plusieurs fois sur une même machine, il faut alors allouer à chacune de ces exécutions des ressources de mémoire et de processeur distinctes au cours de ces exécutions. C'est le système d'exploitation qui gère l'allocation de ces ressources.

Processus

Un processus est dynamique: c'est une instance d'exécution d'un programme sur une machine de son lancement jusqu'à sa fin.

Les systèmes d'exploitation permettent à l'utilisateur de visualiser et gérer les processus grâce à un gestionnaire de processus.

Programmes et processus sous linux

Si vous êtes sous linux ou OSX, vous pouvez simplement lancer un terminal pour ouvrir une console. Sinon vous pouvez lancer une instance jupyterlab en ligne grâce à Binder.

Binder

Sous linux, les programmes sont par convention situées dans les dossiers bin pour binaries en anglais:

  • /bin/: commandes de base nécessaires au démarrage et à l'utilisation d'un système minimaliste.
  • /sbin/: Exécutables pour les administrateurs (abréviation de system binaries, soit binaires système en français).
  • /usr/bin/: Binaires exécutables qui ne sont pas déjà présents dans /bin et donc pas indispensables à un système minimaliste.

On peut lister les programmes avec la commande ls et les exécuter en tapant leur nom dans une console.

# la commande ls vue en première (abbréviation de list en anglais)
ls /bin

ls /sbin

ls /usr/bin

Vous pouvez afficher un programme en particulier grâce à la commande cat.

cat /bin/ls

Comme vous le voyez c'est un fichier binaire car ce programme a été compilé pour s'exécuter plus rapidement.

Vous pouvez lancer un programme en particulier en écrivant son nom (sans préciser son chemin s'il appartient au PATH).

# affichage sortie
echo "Voulez-vous continuer"
# lecture entrée
read 

Maintenant si vous voulez lister les processus en cours d'exécution on utilise la commande ps.

# affiche mes processus en exécution
ps
# affiche tous les processus
ps -A
# affiche une aide simple
ps --help s

Voici un exemple de sortie avec l'option -l pour obtenir plus détails:

jovyan@jupyter-jupyterlab-2djupyterlab-2ddemo-2dgmyobfo6:~$ ps -lA
F S   UID     PID    PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S  1000       1       0  0  80   0 - 137942 epoll_ ?       00:00:45 jupyter-noteboo
0 Z  1000    2293       1  0  80   0 -     0 -      ?        00:00:00 dash <defunct>
4 S  1000    4031       1  0  80   0 -  5116 wait   pts/0    00:00:00 bash
4 S  1000    4900    4031  0  80   0 -  5083 select pts/0    00:00:00 bash
4 S  1000    5105       1  0  80   0 -  5116 wait   pts/1    00:00:00 bash
0 R  1000    5984    5105  0  80   0 -  6910 -      pts/1    00:00:00 ps

On peut créer des affichages particuliers par exemple pour voir quels processus sont les plus gourmands en mémoire: ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head

PID    PPID CMD                         %MEM %CPU
  1       0 /srv/conda/envs/notebook/bi  0.1 17.0
122       1 /srv/conda/envs/notebook/bi  0.0  4.6
 84       1 /bin/bash -l                 0.0  1.7
137      84 ps -eo pid,ppid,cmd,%mem,%c  0.0  0.0
138      84 head                         0.0  0.0

Enfin on peut tuer un processus avec la commande kill.

# tuer avec le PID processus id
kill 122
# tuer par le nom du programme ATTENTION cela tue votre instance binder
# pkill jupyter 

Les états d'un processus

Un processus n'a pas seulement besoin d'accéder au processeur, mais il a souvent besoin d'accéder à des ressources autres comme:

  • La mémoire vive: RAM,
  • La mémoire de masse: disques durs, clés USB, mémoire flash...
  • La lecture ou l'écriture d'un fichier...
  • Les périphériques d'entrée et de sortie: clavier, souris, écran, imprimante...

Ces ressources externes étant beaucoup moins rapides que le processeur, elles bloquent les processus lors de leur exécution.

Ainsi, lors de la vie d'un processus, celui-ci peut passer par trois états:

  • PRÊT: le processus est lancé et attend l'accès au processeur.
  • ÉLU: le processus a obtenu l'accès au processeur: il peut s'exécuter.
  • BLOQUÉ: le processus est en cours d'exécution, mais attend une ressource en mémoire par exemple, il quitte le processeur pour libérer les ressources.

Ordonnancement

À un instant donné, il y a souvent davantage de processus à exécuter que de processeurs.

Lors de leur lacement les processus sont placés dans une file d'attente.

L'ordonnanceur désigne le composant du noyau du système d'exploitation choisissant l'ordre d'exécution des processus sur les processeurs d'un ordinateur.

Il existe divers algorithmes d'ordonnancement:

  • La méthode du tourniquet (Round Robin): l'ordonnanceur traite la file d'attente comme une file circulaire et alloue successivement un temps processeur à chacun des processus de la file.
  • FIFO: First In First Out (voir le cours sur les files)
  • SJF Shortest job first (SJF, ou SJN -Shortest Job Next-).
  • ...

[Article Wikipédia sur l'ordonnancement]{.cite-source}

Interblocage

interblocage

Un interblocage (ou étreinte fatale, deadlock en anglais pour impasse) est un phénomène qui peut se produire en programmation concurrente lorsque des processus s'attendent mutuellement.

Un exemple concret d'interblocage peut se produire lorsque deux processus essayent d'acquérir deux ressources dans un ordre différent.

Process deadlock.svg
  • P1 acquiert R1.
  • P2 acquiert R2.
  • P1 attend pour acquérir R2 (qui est détenu par P2).
  • P2 attend pour acquérir R1 (qui est détenu par P1).

Dans cette situation, les deux processus sont définitivement bloqués.

Deux processus en concurrence pour deux ressources dans un ordre opposé.

Two processes, two resources.gif
By Abacoo - [Own work]{.int-own-work lang="en"}, CC BY-SA 4.0, Link

  • A Un seul processus se déroule.
  • B Le processus ultérieur doit attendre.
  • C Un blocage se produit lorsque le premier processus verrouille la première ressource en même temps que le second processus verrouille la seconde ressource.
  • D Le blocage peut être résolu en annulant et en redémarrant le premier processus.

Il existe plusieurs façons de gérer les interblocages:

  • les ignorer ce qui était fait initialement par UNIX qui supposait que la fréquence des interblocages était faible et que la perte de données encourue à chaque fois est tolérable.
  • les détecter: Un algorithme est utilisé pour suivre l'allocation des ressources et les états des processus, il annule et redémarre un ou plusieurs processus afin de supprimer le blocage détecté
  • les éviter: des algorithmes sont utilisés pour supprimer une des quatre conditions nécessaires à la possibilité de l'interblocage(Conditions de Coffman)
Conditions de Coffman

Coffman a prouvé en 1971 qu'il y a quatre conditions nécessaires pour qu'un blocage puisse avoir lieu.

Voir l'article Wikipédia Conditions de Coffman pour plus de détails.