Vous êtes sur la page 1sur 36

Ecole Nationale Polytechnique d’Oran- Maurice AUDIN

Département de Génie des Systèmes

Intitulé de la matière: Programmation Système

Chapitre2: Gestion des processus


(1ère partie)
Mme Nawel BENDIMERAD

Année universitaire 2021/2022


1
Contenu du Chapitre 2
1/ Introduction
2/ Définition d’un processus
3/ Image mémoire d’un processus
4/ Structure de données associée au processus (BCP)
5/ Etats d’un processus
6/ Mécanisme de commutation de contexte
7/ Processus sous le SE Windows
8/ Processus sous le SE Linux
9/ Ordonnancement des processus

2
1/ Introduction
• La gestion des processus est fondamentale dans un système d’exploitation.
Ce dernier doit permettre entre autres l’allocation des ressources aux
différents processus, leur création, suspension, reprise et terminaison.
• Le processeur est considéré comme le « cerveau » de l’ordinateur.
Composé principalement d’une unité arithmétique et logique (UAL) et d’une
unité de contrôle (ou de commande), il permet d’extraire des instructions de
la mémoire afin de les exécuter.
• L’exécution d’un processus est, en général, une alternance de calculs
effectués par le processeur et de requêtes d’entrée/sortie effectuées par les
périphériques.

3
2/ Définition d’un processus(1)
•Le processus est un concept clé dans un système d’exploitation et
peut être schématisé comme un programme en cours d’exécution.
C’est-à-dire, un programme à l’état actif.
•Un processus représente l’image de l’état du processeur et de la
mémoire au cours de l’exécution d’un programme : le programme
est statique et le processus représente la dynamique de son
exécution.
•Tout processus possède des attributs propres à lui (comme un
numéro d’identification), des ressources qu’il utilise (comme les
fichiers ouverts) et se trouve à tout moment dans un état (par
exemple en exécution ou en attente).
4
2/ Définition d’un processus (2)
•Un processus est constitué de deux parties :
- Un code exécutable du programme en exécution
- Un contexte qui est une image décrivant l’environnement du
processus.
•Un seul processus est exécuté à la fois sur un processeur.
Comme le processeur commute entre les différents processus, on
a une impression de parallélisme mais il s’agit d’un pseudo
parallélisme. Lorsque l'on dispose de plusieurs processeurs, on
exécute plusieurs programmes (processus) en parallèle et c'est un
vrai parallélisme.
•Exemples de processus: Courier électronique, la compression
d’un fichier, le navigateur web, etc. 5
3/ Image mémoire d’un processus
• L’image mémoire (Memory Map) d’un processus représente l’espace
mémoire alloué, qui est composé en plusieurs parties nécessaires au
bon fonctionnement du processus.
• Chaque processus a sa propre image mémoire contenant les
informations suivantes :

– Code: instructions du programme.


– Données: constantes et variables déclarées.
– Tas: espace mémoire qui peut être alloué
dynamiquement en cours d’exécution.
– Pile: valeurs des registres (compteur ordinal,
pointeur de pile),variables locales et paramètres
de fonction, etc.
6
4/ Structure de données associée au processus (BCP) (1)

• Le système d’exploitation gère une table de structures appelée table des


processus dont chaque entrée correspond à un processus particulier. Le
processus y est représenté par une structure de données que l’on nomme le
bloc de contrôle des processus (BCP).
• Chaque structure de données contient les informations suivantes:

1. Identité du processus : chaque processus possède deux noms pour son


identification :
- Un nom externe sous forme de chaîne de caractères fourni par l’usager (c’est
le nom du fichier exécutable).
- Un nom interne sous forme d’un entier fourni par le système. Toute référence
au processus à l’intérieur du système se fait par le nom interne pour des raisons
de facilité de manipulation.
7
4/ Structure de données associée au processus
(BCP) (2)
2. Etat du processus : l’état peut être nouveau, prêt, en exécution, en attente, arrêté,
etc.

3. Contexte du processus : compteur ordinal, mot d’état, registres.

4. Informations sur le scheduling (ordonnancement) : ces informations


comprennent la priorité du processus, des pointeurs sur les files d’attente de
scheduling, etc.

5. Informations sur la gestion mémoire : ces informations peuvent inclure les


valeurs des registres base et limite, les tables de pages ou les tables de segments.

6. Information sur l’état des E/S : l’information englobe la liste de périphériques


d’E/S alloués à ce processus, une liste de fichiers ouverts, etc.

7. Informations de Comptabilisation : ces informations concernent l’utilisation des


ressources par le processus, par exemple, le temps CPU utilisé, etc.
8
4/ Structure de données associée au processus
(BCP) (3)
Remarque:
•Les informations relatives à la structure de données propre à
chaque processus sont sauvegardées dans une zone mémoire
accessible uniquement par le noyau du système d’exploitation.
•Par exemple, sous linux, afin d’obtenir des informations sur les
processus, il est nécessaire de passer par les appels systèmes
suivants: getpid( ), getppid( ), getuid( ), getgid( ), etc.

9
4/ Structure de données associée au
processus (BCP) (4) Exemple

10
5/ États d'un processus (1)
• Dans un système multitâches, plusieurs processus peuvent se
trouver simultanément en cours d'exécution : ils se partagent
l'accès au processeur, ce qui donne lieu à plusieurs
commutations de contexte.
• Si un système informatique ne comporte qu'un seul processeur,
alors, à un instant donné, un seul processus aura accès à ce
processeur. En conséquence, un processus peut prendre
plusieurs états durant son exécution.
Remarque :
• La multiprogrammation a été introduite en partie pour éviter
qu'un programme en attente de fin d'entrées-sorties ne
monopolise le processeur.

11
5/ États d'un processus (2)
Les trois principaux états d’un processus sont les suivants :
• Etat actif ou élu (running): le processus est en exécution, il
utilise alors le processeur.
• Etat prêt ou éligible (ready): le processus attend la libération du
processeur pour s’exécuter, il pourrait utiliser le processeur s’il
était libre et si c’est son tour.
• Etat en attente ou bloqué : le processus attend une ressource
physique ou logique autre que le processeur pour s’exécuter
(exemple : fin d'une entrée-sortie).

12
5/ États d'un processus (3)
Transitions entre états d’un processus

Les transitions entre états provoquent le passage d'un état à un


autre. 13
5/ États d'un processus (4)
Transitions entre états d’un processus
Les changements d’états peuvent avoir lieu dans les différents cas
suivants :
1. Un nouveau processus est créé, son code est chargé en mémoire.
2. Le quantum de temps a expiré ou un processus plus prioritaire a été
admis (réquisition du processeur).
3. Le processus a été sélectionné par l’ordonnanceur (allocation du
processeur).
4. Le processus est en attente d’une ressource.
5. La ressource ou les données deviennent disponibles, donc le
processus est réveillé, il passe dans la file d’attente des processus
prêts.
6. Le processus sort des files d’attente de l’ordonnanceur.

14
5/ États d'un processus (5)
Exemple
• L’état d’un processus est défini par l’activité courante de celui-ci.
Les processus peuvent interagir entre eux.
• Exemple:
Commande linux: who | wc -l
• Le premier processus qui exécute « who » liste les utilisateurs
connectés et envoie ses résultats dans un tube.
• Le second processus qui exécute « wc -l » compte le nombre de
lignes lui parvenant par le tube.
• Ces deux processus sont lancés de manière concurrente.
Cependant, le processus « wc » peut être prêt à s’exécuter mais il
est obligé d’attendre les informations provenant du processus
« who ». Dans ce cas le processus « wc » se bloque. 15
6/ Mécanisme de commutation de contexte (1)

• L’utilisation des blocs de contrôle des processus est très importante


dans le système d’exploitation, car dans un système
multiprogrammé, on a souvent besoin d’attribuer le processeur à un
autre processus.
• Il faut donc mémoriser toutes les informations nécessaires afin de
pouvoir éventuellement reprendre l’exécution du processus courant
dans le même état.
• Par exemple, il faut absolument se rappeler à quelle instruction le
processus a été interrompu.

16
6/ Mécanisme de commutation de contexte (2)
Exemple

17
6/ Mécanisme de commutation de contexte (3)
• Périodiquement, le système d’exploitation décide d’interrompre un
processus pour en exécuter un autre.
• Les étapes du changement de contexte sont les suivantes :
- Suspendre l’exécution du processus P0
- Sauvegarder l’état du processus P0 dans son PCB
- Choisir un nouveau processus P1
- Restaurer le PCB du processus P1
- Démarrer l’exécution du processus P1

• La commutation de contexte consiste à changer les contenus des


registres du processeur central par les informations de contexte 18du
7/ Processus sous le SE Windows (1)
• Windows offre un certain nombre de fonctions pour permettre au programmeur
et au système d’exploitation de manipuler les processus.
• L’unité de base des processus sous Windows est le « thread », tout processus
créé contient au moins un « thread ».
• Un processus Windows se compose des éléments suivants:
- Un identificateur unique appelé ID processus.
- Un espace d’adressage virtuel privé.
- Un programme exécutable qui définit le code et les données initiaux.
- Une liste de handles (gestionnaires) ouverts qui pointent vers diverses
ressources systèmes telles que les ports de communication, les fichiers, etc.
- Un contexte de sécurité appelé jeton d’accès qui identifie l’utilisateur, les
groupes de sécurité et les privilèges associés au processus.
- Au moins un thread d’exécution.
19
7/ Processus sous le SE Windows (2)

• Il y a une création d’un processus Windows lorsqu’une


application appelle une fonction de création de processus comme
CreateProcess.
• La fonction CreateProcess permet de créer un processus dont les
caractéristiques sont données en paramètres de l'appel système.

• Exemple :

20
#include <windows.h>
#include <stdio.h>
int main( ){
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) ); ZeroMemory( &pi, sizeof(pi)); si.cb = sizeof(si); // Start the child process.
if( !CreateProcess( “Fils.exe”, //nom ou chemin du fichier exécutable
NULL, //Il n’y a pas de ligne de commande.
NULL, // handle de processus non héritant.
NULL, // handle de thread non héritant.
FALSE, // identificateur de l’objet processus/thread non héritant.
0, // Aucun drapeau de création de processus.
NULL, // Utiliser les mêmes chaînes d’environnement que le processus père.
NULL, // Utiliser le répertoire courant du processus père.
&si, // Pointeur sur la structure STARTUPINFO.
&pi ) // Pointeur sur la structure PROCESS_INFORMATION. ) ErrorExit( "CreateProcess failed." );
WaitForSingleObject( pi.hProcess, INFINITE );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread ); return 0; } 21
8/ Processus sous le SE Linux (1)
8.1 Création de processus (1)
• La création d’un nouveau processus sous le système d’exploitation
Linux est réalisée à partir d’un programme en cours d’exécution à
l’aide de la fonction fork( ).
• Le processus d’origine est appelé processus père, et il garde son PID,
et le nouveau processus créé s’appelle processus fils, et possède un
nouveau PID.
• Les caractéristiques de la fonction fork( ) sont les suivantes :
 Le processus père et le processus fils ont le même code source mais
ne partagent pas leurs variables au cours d’exécution.
 Tout processus Linux (excepté le processus racine) est créé à l’aide
de cet appel système. 22
8/ Processus sous le SE Linux (2)
8.1 Création de processus (2)
 A l’issu de l’exécution de l’appel fork( ) par le processus père,
chaque processus reprend son exécution au niveau de l’instruction
suivant le fork( ).
 Afin de différencier les traitements à réaliser dans le cas du
processus père et du processus fils, on utilise la valeur de retour de
la fonction fork( ), en utilisant un if et un else ou un switch :
- Si l’appel à fork( ) échoue, le processus fils n’est pas créé et la
valeur de retour est −1.
- Dans le processus fils, la valeur de retour vaut 0.

23
8/ Processus sous le SE Linux (3)
Début et fin d’un processus
 Un processus a généralement un début et une fin
 Début : création par un autre processus - par fork()
• il existe un processus “primitif” créé à l’origine du système
 Fin
• terminaison du processus (à la fin du programme) - par exit()
• destruction par un autre processus - par kill()
• certains processus ne se terminent pas (réalisant des fonctions du
système)
 Dans le langage de commande
 un processus est créé pour l’exécution de chaque commande
 on peut créer des processus pour exécuter des commandes en
(pseudo)-parallèle :
Exemple:
$ prog1 & prog2 &
(deux processus sont créés pour exécuter prog1 et prog2 )
24
8/ Processus sous le SE Linux (4)
Synchronisation entre un processus père et
ses fils
• Le processus fils termine son exécution par exit(statut), où
statut est un code de fin.
• La terminaison du processus père n’entraine pas la
terminaison de ses fils.
• Lorsqu’un processus fils se termine avant son père, il passe à
l’état zombie.
• Un processus zombie ne peut plus s’exécuter, mais consomme
encore des ressources (tables). Il faut éviter de conserver des
processus dans cet état.

25
8/ Processus sous le SE Linux (5)
Synchronisation entre un processus père et
ses fils
• Afin de terminer complètement un processus fils zombie et
donc libérer les ressources associées, le processus père peut
faire appel à une fonction de synchronisation de type wait() ou
waitpid().

26
8/ Processus sous le SE Linux (6)
La fonction wait()
• pid_t wait(int *status) suspend l’exécution du processus père
(appelant) jusqu’à ce que l’un de ses fils se termine.
• La synchronisation du processus père et de l’ensemble de ses fils
nécessite donc autant d’appel à wait() que de processus fils.
• pid_t waitpid(pid_t pid, int *status, int options) permet de
spécifier le PID du fils dont la fin est attendue.
• Le second argument de waitpid() permet de récupérer une
information relative à l’exécution du fils dont on attend la
terminaison.
• Cette information peut être transmise par le processus fils au
moyen de la fonction void exit(int status) qui permet la
terminaison normale du processus.

27
8/ Processus sous le SE Linux (7)
La fonction wait(int *status)
• Valeur de retour :
Si aucun processus fils => -1 ;
Sinon, pid du processus fils s'utilise du coté du processus
père.
• Sémantique :
 si aucun des processus fils n'est terminé, le processus père
se bloque.
 la fin du blocage arrive soit par la fin d’exécution du
processus fils, soit par une « interruption » du processus père
(réception d'un signal)

28
8/ Processus sous le SE Linux (8)
La fonction waitpid(pid_t pid, int *status,
int options)
• valeur de retour :
• -1 : erreur (pas de fils)
• 0 : échec (il n’existe aucun processus fils terminé)
• >0 : pid d'un fils (zombie) s'il existe
• argument pid (sélection processus à attendre) :
– Si le processus fils mentionné par pid s’est déjà terminé
avant l’appel à cette fonction, il deviendra "zombie"
• options :
• 0 : bloquant
• 1 : non bloquant
29
8/ Processus sous le SE Linux (9)
La fonction exit(int status)
• un appel à la primitive exit() provoque la terminaison du
processus effectuant l’appel avec un code retour status.
• Le père du processus qui effectue un exit reçoit son code retour à
travers un appel à wait.
• Ce code est
- soit constitué à partir de la valeur passée en paramètre à exit par
le fils (terminaison normale du fils (utiliser
WEXITSTATUS(status))).
- soit un code d'erreur fabriqué par le SE (terminaison anormale
du fils) et indiquant la raison de cette terminaison (par exemple
processus tué).

30
8/ Processus sous le SE Linux (10)
Interprétation de la valeur renvoyée par
exit(int status)
• L’interprétation de la valeur récupérée doit, pour des raisons de
portabilité être réalisée par l’intermédiaire de macro-fonctions
prédéfinies dans le fichier d’en-tête <sys/wait.h>.
• Elles sont appelées avec la valeur fournie au retour de l’appel à
wait ou waitpid.
• Exemples:

31
8/ Processus sous le SE Linux (11)
Recouvrement de processus sous Linux
• Le recouvrement de processus permet de remplacer par un autre
code le code exécuté par un processus.
• Le programme et les données du processus sont alors différents,
mais celui-ci garde le même pid, le même père et les même
descripteurs de fichiers.
• C’est ce mécanisme qui est utilisé lorsque, par exemple, nous tapons
la commande ls, ou que nous lançons un programme après l’avoir
compilé:
 le terminal de commande dans lequel cette commande est tapée fait
un fork() ;
 le processus ainsi créé est recouvert par l’exécutable désiré ;
 pendant ce temps, le terminal de commande (le père) attend que le
fils se termine grâce à wait() si la commande n’a pas été lancée en
tâche de fond. 32
8/ Processus sous le SE Linux (12)
La fonction exec
• Il est possible de demander à un processus d’exécuter un autre
programme que son processus père, en utilisant une variante de
la fonction exec (qui remplace le programme courant par un
autre programme).
• Les primitives de recouvrement constituent un ensemble
d’appels système (de type exec*()) permettant à un processus de
charger en mémoire un nouveau code exécutable.
• Le code de remplacement, spécifié comme argument de l’appel
système de type exec*(), écrase le code du processus en cours.
• Des données peuvent être passées au nouveau code exécutable
qui les récupère via les arguments de la fonction exec*() utilisée.

33
La fonction exec
Il existe 6 primitives de recouvrement de type exec*().
• Les deux fonctions de base sont :
– int execl(const char *path, const char *arg0, const char *arg1, ... , const char
*argn, NULL): path est le chemin d’un exécutable à partir du répertoire courant,
arg0, arg1, ... , argn, NULL est la liste des arguments à passer au nouveau
programme.
– int execv(const char *path, const char *argv[]): Le premier paramètre est le
même que celui d’execl et le deuxième paramètre argv[] est un tableau contenant les
arguments à passer au nouveau programme.

• Nous pouvons utiliser d’autres fonctions telles que :


– int execle(const char *path, const char *arg0, const char *arg1, ... , const char
*argn, NULL, const char *envp[]): même fonctionnement qu’execl() avec en plus le
chargement d’un nouvel environnement. L’argument envp représente un pointeur sur
un tableau de pointeurs sur des chaînes de caractères définissant l’environnement.
– int execve(const char *path, char *const argv[], const char *envp[]) : même
fonctionnement qu’execv() mais elle prend la description de l’environnement comme
argument supplémentaire. 34
La fonction exec
– int execlp(const char *file, const char *arg0, const char
*arg1, ..., const char *argn, NULL): même fonctionnement
qu’execl(), mais si le nom du fichier n’est pas un nom complet, le
système utilisera le chemin de recherche des commandes pour trouver
dans quel répertoire se trouve le programme.
– int execvp(const char *file, const char *argv[]): même
fonctionnement qu’execv(), mais si le nom de fichier n’est pas un
nom complet, le système recherche dans quel répertoire se trouve le
programme.
• Leur différence principale réside dans la manière de passer le code
de remplacement.
• De manière générale, il s’agit d’une chaine de caractères
constituant le chemin vers l’exécutable correspondant.
• L’utilisation de ces primitives nécessitent l’inclusion de la
bibliothèque « unistd.h ». 35
Exemple d’execv()
• int execv(const char *path, char *const argv[]) est une des
primitives de recouvrement.
• Cette fonction recouvre le processus avec l’exécutable indiqué par
la chaîne de caractère path (le chemin d’accès à l’exécutable).
• argv[] est un tableau de chaînes de caractères contenant les
arguments à passer à l’exécutable.
 argv[0] contient la chaine de caractères correspondant au nom du
fichier exécutable,
 argv[1] est la chaine de caractères correspondant au premier
argument, …
 Le dernier élément du tableau doit contenir NULL.
Remarque: Si l’appel d'une primitive exec est réussi, donc la partie de
code qui suit cet appel ne s'exécute pas. Ce code s’exécute que dans le
cas où la primitive exec n'a pas pu lancer le processus de
remplacement (un cas d’erreur). 36

Vous aimerez peut-être aussi