Un système d’exploitation se compose de processus. Ces derniers, responsables de la stabilité et la sécurité du système, sont exécutés dans un ordre bien précis et observent des liens de parenté entre eux. On distingue deux catégories de processus, ceux axés sur l’environnement utilisateur et ceux sur l’environnement matériel.
Les processus
Principes
Lorsqu’un programme s’exécute, le système va créer un processus qui lui est associé en plaçant les données et le code du programme en mémoire et en créant une pile d’exécution. De ce fait un processus est une instance (dynamique) d’un programme auquel est associé un environnement processeur (CO, PSW, registres) et un environnement mémoire.
Au seins des systèmes UNIX, les processus sont identifiés par leur PID (ou Process Identifiant, un identifiant unique) et y sont organisés de façon hiérarchique. Il existe une relation père / fils entre les processus, un processus fils est le résultat de l’appel système de la primitive fork()
par le processus père qui duplique son propre code pour créer un fils. Le PID du fils est renvoyé au processus père pour qu’il puisse dialoguer avec. Chaque fils possède l’identifiant de son père, le PPID (ou Parent Process Identifiant).
Note : Les processus ne sont pas à confondre avec les threads (dit aussi processus légers). Chaque processus (parent, enfant) possède son propre contexte mémoire (ressources et espace d’adressage) alors que les threads issus d’un même processus partagent ce même contexte.
Création des processus
Avant le lancement du système, le chargeur de démarrage (ou d’amorce) fait appel à la fonction start_kernel()
du fichier init/main.c
. Cette fonction va créer le tout premier processus : le swapper (ou Processus 0, ou encore sched pour scheduler ) qui occupera la première entrée de la table des processus. Le swapper va ensuite créer deux autres processus, le processus init et le processus [kthreadd]
et va s’endormir.
Avant le lancement du système, le chargeur de démarrage (ou d’amorce) fait appel à la fonction start_kernel()
du fichier init/main.c
. Cette fonction va créer le tout premier processus : le swapper (ou Processus 0, ou encore sched pour scheduler ) qui occupera la première entrée de la table des processus. Le swapper va ensuite créer deux autres processus, le processus init
et le processus [kthreadd]
et va s’endormir.
A partir de ce moment là, nous pouvons considérer qu’il existe 2 espaces au sein du système. Un espace utilisateur avec init
au sommet de la hiérarchie et un espace noyau avec [kthreadd]
.
Notons que Init
et [kthreadd]
étant tout les deux des fils du swapper ont leur PPID égal à 0. La commande ps
permet de le vérifier.
# ps -aef |
Arborescences
Espace utilisateur
Au sommet de l’espace utilisateur se trouve le processus init
, ayant le PID n°1, qui est le premier à avoir été lancé. Il se chargera ensuite de créer les autres processus nécessaires au fonctionnement du système, notamment les processus daemons
et les processus gettys
qui à leur tours créeront d’autre processus fils et ainsi de suite. Init
sera ici l’ancêtre de tous les processus.
Les processus gettys
Les processus getty
(get teletype) sont chargés de la surveillance des terminaux. Ils permettent entre autres aux utilisateurs de se connecter.
# ps -aef |
Quand un utilisateur veut se connecter à un terminal, le processus getty
va créer un nouveau processus fils, le processus login
. Ce dernier va vérifier à l’aide du fichier /etc/passwd
la correspondance login/mot de passe et les autorisations de l’utilisateur. Si la connexion est réussi, le processus login
va à son tour créer un nouveau processus fils, le processus shell
(interpréteur de commandes). Il va analyser si l’utilisateur entre une commande et créera un nouveau processus chargé de l’exécuter. Ce dernier processus prendra fin lorsque la commande (ou le programme lancé en ligne de commande) se terminera.
# ps axjf |
Les processus daemons
Les daemons
sont des processus, pour la plupart lancé au démarrage du système, qui restent en tâche de fond jusqu’à ce qu’on fasse appel à eux. Leurs noms se terminent généralement par la lettre d (pour daemon).
UID PID PPID C STIME TTY TIME CMD |
Parmi les plus connus nous avons par exemple crond
(tâches planifiées), inetd
(surveillance réseau), rsyslogd
(logs du système), lpd
(gestion de l’imprimante), etc. Liste non exhaustive : Unix_daemons
Espace Noyau
Cet espace est occupé par les threads noyau (ou kthreads
, ou encore processus noyau) qui gèrent la partie hardware du serveur (c’est pourquoi ils sont lancés depuis le swapper) et ont une priorité haute. Ils s’exécutent dans l’espace d’adressage du noyau.
Au somment de cet espace se trouve le daemon [kthreadd]
, processus qui se chargera de lancer tous les autres kthreads
, reconnaissables de par leurs nom entre crochets [], [kthreadd]
est donc l’unique père de cette hiérarchie et de ce fait tous les kthreads
présents dans cet espace (sauf [kthreadd]
lui même) ont un PPID de 2.
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND |
Parmi les plus connus nous avons par exemple [kswapd0]
(daemon du swap), [kupdate]
(cache disque), etc.
Conclusion :
C’est le système qui, normalement, se charge de la gestion des processus, cependant il est possible d’intervenir avec l’aide de commandes comme ps
, top
, htop
. Ces commandes s’avèrent très pratiques en cas de problèmes (consommation mémoire excessive, processus zombie, …). Elles permettent dans la plupart des cas un contrôle assez étendu et d’avoir une bonne vision d’ensemble sur le système et les processus.