Vous êtes sur la page 1sur 70

Systèmes d'exploitation

Chapitre 02: Les processus & Les Threads

Maroun CHAMOUN
maroun.chamoun@usj.edu.lb
Génie Logiciel
USJ FI
Semestre 4

Partie I

Notion des processus

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 2/70


Programme et Processus Génie Logiciel
USJ FI
Semestre 4

• Un programme (program) est une séquence statique d’instructions.


On peut exécuter plusieurs instances du même programme simultanément
en mémoire, alors qu’il n’y a qu’une seule image (fichier) sur le disque.

• Un processus (process) est un conteneur stockant les ressources utilisées


lors de l’exécution de l’instance d’un programme.

• Le système crée les processus de l’utilisateur, leur alloue de la mémoire

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 3/70


États d’un processus Génie Logiciel
USJ FI
Semestre 4

• Problème:
– Comment gérer l’exécution de plusieurs processus sur beaucoup moins d’UCT
• Un processus sera:
– parfois en exécution sur une UCT,
– parfois en attente d’une E/S,
– parfois en attente d’une UCT
• Système monoprocesseur
– Pour fournir l’illusion que plusieurs processus tournent en parallèle, le système
interrompt et reprend les processus.
– A un instant donné, 1 seul processus actif (ÉLU)
– Autre processus:
• en attente d’exécution (PRET)
• bloqué en attente de ressources (BLOQUÉ)

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 4/70


États de processus Génie Logiciel
USJ FI
Semestre 4

• Au fur et à mesure qu’un processus est exécuté, il change d’état


– nouveau: le processus vient d’être créé
– Exécutant (ou élu) - running: le processus est en train d’être exécuté par une UCT
– Attente (ou bloqué) - waiting: le processus est en train d ’attendre un événement
(par exemple la fin d’une opération d’E/S)
– Prêt - ready: le processus est en attente d’être exécuté par une UCT
– Terminé - terminated: fin d’exécution
Cycle de vie d’un processus

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 5/70


Génie Logiciel
USJ FI
Semestre 4

Partie II
Commutation de processus et
Process Control Block

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 6/70


Sauvegarde d’informations de processus Génie Logiciel
USJ FI
Semestre 4

• Un processus s’exécute sur une UCT de façon intermittente


• Chaque fois qu’un processus reprend l’UCT (transition prêt → exécution) il
doit la reprendre dans la même situation où il l’a laissée (même contenu de
registres UCT, etc.)
• Donc au moment où un processus sort de l’état exécution il est nécessaire
de sauvegarder ses informations essentielles, qu’il faudra récupérer quand il
retourne à cet état

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 7/70


Process Control Block (PCB) Génie Logiciel
USJ FI
Semestre 4

Informations utilisées
Informations dont le SE a
besoin à tout moment: uniquement lorsque le
processus est en exécution:

– Numéro d’identification
– Compteur de programme (PC)
unique (PID)
– Valeurs des registres
– Informations sur son
– Liste des fichiers ouverts
processus père et ses
– Liste des périphériques ouverts
processus fils
– …
– Etat du processus
– Espace d’adressage
– Priorité
– Information de comptabilité
–…
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 8/70
Table des processus Génie Logiciel
USJ FI
Semestre 4

• Le SE maintient une entrée par processus: le PCB


• Cette table permet au SE de localiser et gérer tous les processus
Table des Processus:
PCB [ MAX-PROCESSUS ]

PCB (Process Control Block):


informations requises pour permettre
au SE de gérer un processus

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 9/70


Contexte d’exécution d’un processus Génie Logiciel
USJ FI
Semestre 4

• Etat courant du processus


– Code du programme exécuté
– Données statiques et dynamiques
– Informations qui caractérisent l’état dynamique du processus
• Compteur de programme (PC / CO)
• Etat des registres
• Liste des fichiers ouverts
• Variables d’environnement
• Image mémoire (état de l’espace d’adressage)
• … Un processus a:
– un programme
• A sauvegarder lorsque le processus est commuté
– des données
• A restaurer lorsque le processus reprend la main – un état courant

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 10/70


Génie Logiciel
USJ FI
Semestre 4

Partie III
Les processus sous UNIX

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 11/70


Etats d’un processus Unix Génie Logiciel
USJ FI
Semestre 4

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 12/70


Quelques appels systèmes relatifs aux processus Génie Logiciel
USJ FI
Semestre 4

Appel système Description


pid = getpid () Retourne le PID du processus courant.
ppid = getppid () Retourne le PID du processus parent.
pid = fork() Crée un processus fils identique au père.

pid = wait() Permet au processus père d’attendre la terminaison


d’un fils.
pid = waitpid(pid, status, options) Permet au processus père d’attendre la terminaison
d'un fils précis (ayant le pid précisé en paramètre).

s = execve (nom, params, env) Provoque l’exécution d’un autre programme par le
processus courant.
exit (status) Termine le processus courant.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 13/70


Relation entre les processus UNIX Génie Logiciel
USJ FI
Semestre 4

▪ Tout processus Unix peut créer un ou plusieurs processus qui, à leur tour,
peuvent en créer d’autres
– Arborescence de processus avec un rapport père -fils entre processus créateur et
processus créés

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 14/70


Mécanisme de création des processus Génie Logiciel
USJ FI
Semestre 4

▪ Un processus est créé par un processus père qui l'active grâce au


mécanisme de duplication (fork, fourchette).
▪ La duplication du père donne naissance à un processus fils, copie
conforme du père et qui hérite de toutes les propriétés du père.
▪ Le processus père peut se mettre en attente (wait) de la fin d'exécution
du fils (dispositif de synchronisation).
▪ Le processus fils exécute alors son propre programme (exec) qui peut être
un programme système ou utilisateur ou une commande.
▪ La terminaison (fin) du processus fils par la fonction exit réveille le
processus père qui peut alors continuer son travail.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 15/70


Primitive fork() Génie Logiciel
USJ FI
Semestre 4

▪ pid_t fork( )
▪ La seule manière de dupliquer un processus est d’utiliser fork
– Tout processus Unix/Linux hormis le processus 0 est créé à l’aide de cette primitive.
▪ Cette primitive permet la création dynamique d’un nouveau processus qui
est une copie exacte du processus appelant:
– il s’appelle processus fils. ret=fork()
– Il hérite de son père :
• le même code ret==0 ret>0
• une copie de la zone de données
• la priorité On est dans le On est dans le
• les propriétaires processus fils processus père
• les descripteurs de fichier
• …
– Le processus fils s’exécute de manière concurrente avec le processus qui l’a créé, on
ne peut pas faire d’hypothèse sur celui qui exécutera la prochaine instruction.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 16/70


Primitive fork() Génie Logiciel
USJ FI
Semestre 4

Après le fork():
• Le père et le fils vont poursuivre leurs
exécutions à partir de l’instruction qui suit
l’appel au fork mais chacun a sa propre zone
de données.
• Le père récupèrera dans sa variable ret, le
PID du fils créé.
• Le fils récupèrera dans sa variable ret la
valeur 0.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 17/70


Primitive fork() Génie Logiciel
USJ FI
Semestre 4

#include <iostream> $ make fork1


#include <unistd.h> g++ fork1.cpp -o fork1
using namespace std; $ ./fork1
int main () { Pere: PID = 6281
int pid; Fils: PID = 6281
switch ( pid = fork( ) ) {
case -1: /* fork échoue */
perror("appel fork a echoue");
exit(1);
case 0: /* valeur retournée au processus-fils */
cout<<"Fils: PID = " << getpid()<<endl;
break;
default: /* processus père */
cout<<"Pere: PID = " << pid<<endl;
sleep(1); // dormir pendant 1 seconde
break;
}
} /* end main */
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 18/70
Fork itératif Génie Logiciel
USJ FI
Semestre 4

• Boucle de création de nbfils processus fils:


for (i=0 ; i < nbfils ; i++)
{
val=fork();
if (val==0)
{
/* un fils */
int n,num;
char message[15];
cout<<"je suis le fils " <<i<<" de ID " << getpid() << " et de pere " << getppid()<<endl;
}
}

• Si nbfils=5, quel est le nombre de processus créés dans ce programme?

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 19/70


Fork itératif Génie Logiciel
USJ FI
Semestre 4

• Version correcte:
for (i=0 ; i < nbfils ; i++)
{
val=fork();
if (val==0)
{
/* un fils */
int n,num;
char message[15];
cout<<"je suis le fils " <<i<<" de ID " << getpid() << " et de pere " << getppid()<<endl;
……
exit(i); /* ou break; */
}
}

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 20/70


Exemple Complet Génie Logiciel
USJ FI
Semestre 4

#include <iostream>
#include <unistd.h>
using namespace std;
int main ( )
{
pid_t p;
int i, n=5 ;
for (i=1; i<n; i++) {
p = fork();
if (p > 0 ) break ;
cout<<" Processus " << getpid() << " de père " << getppid() << ". \n" ;
}
sleep(1); // dormir pendant 1 seconde
return 0 ;
}

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 21/70


Exemple Complet Génie Logiciel
USJ FI
Semestre 4

$ make fork2
g++ fork2.cpp -o fork2
$ ./fork2
Processus 23707 de père 23706.
Processus 23708 de père 23707.
Processus 23709 de père 23708.
Processus 23710 de père 23709.
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 22/70
Synchronisation père / fils Génie Logiciel
USJ FI
Semestre 4

▪ Un processus peut récupérer des informations sur un fils qui vient de se


terminer grâce à wait.
pid_t wait(int *status)
suspend l'exécution du processus jusqu'à ce qu’un de ses fils se termine
▪ Exemple: retval = wait(&status)
▪ si le processus n'a aucun fils, l'appel se termine instantanément, et retourne
la valeur –1
▪ s'il existe des fils, mais aucun dans l'état zombie, l'appel est bloquant.
▪ Dès qu'un fils est dans l'état zombie, l'appel se termine et retourne le PID de
ce fils; status contient le code de terminaison du fils (paramètre de l'appel
exit() du fils)

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 23/70


Synchronisation père / fils Génie Logiciel
USJ FI
Semestre 4

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 24/70


Synchronisation père / fils Génie Logiciel
USJ FI
Semestre 4

▪ Interprétation de la valeur renvoyée par status


retval = wait(&status)
▪ Pour un processus qui s’est terminé normalement, c’est-à-dire soit par une
instruction return(n), soit par un appel exit(n), l’octet de poids faible de n
est récupéré dans le second octet de status.
▪ Pour un processus qui s’est terminé accidentellement à cause du signal de
numéro sig, l’entier status est égal à sig, éventuellement augmenté de la
valeur décimale 128 si une image mémoire ( fichier core) du processus a été
créée à sa terminaison.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 25/70


Exemple Génie Logiciel
USJ FI
Semestre 4

#include <iostream>
#include <unistd.h>
#include <wait.h>
int main( ) {
int i , pidfils , etat ;
std::cout<<"Début d'exécution du programme père\n";
if ( pidfils = fork( ) ){
std::cout<<"dans le processus père pidfils=pid de fils="<<pidfils<<std::endl ;
i = wait ( &etat ) ; /* père attend ici */
}
else { /* sinon exécuter fils */
int pid ;
std::cout<<"\n Début d'exécution du processus fils\n";
pid=getpid(); /*primitive qui renvoie le numéro du processus courant */
std::cout<<"les 8 bits du poids faible de pid valent "<< pid % 256 <<std::endl ;
std::cout<<"le processus fils se termine\n";
exit( pid ) ;
}
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 26/70
Exemple (Suite) Génie Logiciel
USJ FI
Semestre 4

/* père continue ici après fin de fils */


std::cout<<"\nDans le processus père: Etat="<<etat%256<<" " <<etat/256<<std::endl ;
/* etat%256 (etat&0xff) donne les 8 bits de poids faible de l'etat de retour */
/* etat/256 (etat>>8) donne les 8 bits de poids fort de l'etat de retour */
std::cout<<" et la valeur de wait=pid de fils="<<i<<std::endl ;
exit( 0 ) ;
}

Début d'exécution du programme père


Dans le processus père jeton=pid de fils=499
Début d'exécution du processus fils
les 8 bits du poids faible de pid valent 243
le processus fils se termine
Dans le processus père : Etat=0 243 et la valeur de wait=pid de fils=499

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 27/70


Synchronisation père / fils Génie Logiciel
USJ FI
Semestre 4

▪ L’appel wait() ne permet pas de préciser quel processus on attend, et l’appel


est bloquant si le processus appelant a des fils, tous non zombis.
▪ waitpid() permet de lever ces limitations
pid_t waitpid( pid_t pid , int * status , int option);
▪ pid peut être :
– −1 : attente de n’importe quel processus fils,
– > 0 : attente du processus de pid pid.
– < -1 : tout processus fils dans le groupe |pid|
– 0 : tout processus fils du même groupe que l’appelant
▪ Option fréquente: WNOHANG : non bloquant.
▪ La valeur de l’entier status, au retour d’un appel réussi de l’une des
primitives wait ou waitpid, permet d’obtenir des informations sur la
terminaison ou l’état du processus (dans le cas de la primitive waitpid
appelée avec l’indicateur WUNTRACED).
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 28/70
Exemple Génie Logiciel
USJ FI
Semestre 4

#include <iostream>
#include <unistd.h>
#include <wait.h>
int main() {
pid_t pere,fils;
int vingt, x=1;
std::cout<<"C'est partis!\n";
switch(fils = fork()) {
case -1:
std::cerr<<"erreur, je sors\n";
exit(1);
case 0: /* c'est le fils */
std::cout<<getpid()<<": Je suis le fils de "<<getppid()<<std::endl;
sleep(1);
x=2; $ make wait2
std::cout<<getpid()<<": Je sors \n"; g++ wait2.cpp -o wait2
exit(20); $ ./wait2
default: C'est partis!
std::cout<<getpid()<<": Je suis le pére de "<<fils<<std::endl; 35925: Je suis le pére de 35926
waitpid(fils, &vingt, 0); 35926: Je suis le fils de 35925
std::cout<<getpid()<<": Le processus fils "<<fils<<" est sorti \n";
35926: Je sors
}
} /* FIN du main */ 35925: Le processus fils 35926 est sorti

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 29/70


Primitives de recouvrement Génie Logiciel
USJ FI
Semestre 4

▪ L’exécution d’un nouveau code ne peut se faire que par le recouvrement du


code d’un processus existant grâce à l'utilisation d'une primitive de type
exec qui permet de charger un fichier exécutable en remplaçant le
processus en cours d'exécution.
▪ Les données du processus courant sont perdues et il n'y a pas de retour
(sauf en cas d'erreur).

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 30/70


Primitives de recouvrement Génie Logiciel
USJ FI
Semestre 4

▪ Effet:
– Charge le nouveau code du processus et « repart à 0 » avec le nouveau code,
– réinitialise la pile,
– réinitialise la zone data.
– La zone U-area n'est (presque) pas touchée:
• Il garde son pid, ppid, son propriétaire et groupe réel, son répertoire courant, son umask, ses
signaux pendants, ...
• Il change de propriétaire/groupe effectif si le setuid/setgid bit du binaire qu’il exécute est
positionné.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 31/70


Primitives de recouvrement Génie Logiciel
USJ FI
Semestre 4

int execl(char *path, char *arg0, ...,NULL);


int execv(char *path, char * argv[]);
int execle(char *path,char *arg0,...,NULL,char* envp[]);
int execve(char *file, char * argv[], char * envp[]);
int execlp(char *file, char *arg0, ... , NULL );
int execvp(char *file, char * argv[]);

6 variantes

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 32/70


Primitives de recouvrement Génie Logiciel
USJ FI
Semestre 4

▪ Variantes: selon le mode de passage des arguments (vecteur ou liste), selon


la présence ou non de l’argument path, selon le passage ou non d’un nouvel
environnement au processus
▪ Les fonctions execl* spécifient les arguments comme une liste.
▪ Les fonctions execv* spécifient les arguments comme un vecteur.
▪ Dans les 2 cas, on spécifie :
1. le fichier binaire à exécuter,
2. les arguments, sous forme liste ou vecteur,
▪ Les fonctions exec(v/l)p permettent de chercher le binaire dans les
répertoires spécifiés par la variable d’environnement PATH,
▪ Les fonctions exec(v/l)e permettent de passer en dernier argument un
environnement char *env[].
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 33/70
Exemple Génie Logiciel
USJ FI
Semestre 4

#include <iostream> default:


#include <unistd.h> std::cout<<getpid()<<": Je suis le pere de "<<fils<<"\n";
#include <wait.h> waitpid(fils, NULL, 0);
int main() { std::cout<<getpid()<<": Le processus fils "
char *argu[3]; <<fils<<" est sorti \n";
int pere,fils; break;
switch(fils = fork()) { }
case -1: } /* FIN du main */
std::cerr<<"erreur, je sors\n";
exit(1); $ make exec
case 0: /* c'est le fils */ g++ exec.cpp -o exec
std::cout<<getpid()<<": Je suis le fils de " $ uname -a
<<getppid()<<"\n"; Linux ubuntu20 5.8.0-53-generic #60~20.04.1-Ubuntu SMP Thu May 6
argu[0] = (char*)"uname"; 09:52:46 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
argu[1] = (char*)"-a"; $ ./exec
36055: Je suis le pere de 36056
argu[2] = NULL;
36056: Je suis le fils de 36055
execv("/bin/uname", argu); Linux ubuntu20 5.8.0-53-generic #60~20.04.1-Ubuntu SMP Thu May 6
perror("execv!!!"); 09:52:46 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
exit(1); 36055: Le processus fils 36056 est sorti

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 34/70


Primitives de recouvrement: Le shell Génie Logiciel
USJ FI
Semestre 4

▪ L'exécution d'une commande telle que "ls" sous Unix agit de cette manière :
– le shell est dupliqué,
– la copie du shell est transformée en la commande ls,
– ls termine et le shell principal reprend la main.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 35/70


Génie Logiciel
USJ FI
Semestre 4

Partie IV
Fin d’exécution d’un processus
et gestion des signaux

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 36/70


Fin d’exécution d’un processus Génie Logiciel
USJ FI
Semestre 4

Conditions de fin d’exécution:


• Sortie normale (volontaire)
• Sortie avec erreur (volontaire)
• Erreur fatale (involontaire)
• Tué par un autre processus (involontaire)

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 37/70


Terminaison d’un processus Génie Logiciel
USJ FI
Semestre 4

void exit (int status)


– termine normalement l'exécution d'un processus
– le paramètre status est un code de terminaison, qui est fourni au processus-père
(convention: status = 0 indique une terminaison normale)
▪ Lorsqu'un processus se termine (exit):
– Son état de terminaison est enregistré dans son PCB
– Ses ressources sont libérées
– Il passe à l’état zombie
– Son PCB est conservé jusqu’à ce que son processus père ait récupéré cet état de
terminaison

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 38/70


Signaux: définition Génie Logiciel
USJ FI
Semestre 4

• Le signal est un mécanisme asynchrone de communication interprocessus


– informer les processus de l'occurrence d'événements asynchrones (reçu à n’importe
quel moment).
– Il ne transporte pas d'informations.
– Considéré comme interruption logicielle.
– Il peut changer le déroulement d’un processus.
• Indique à un processus l’occurrence d’un événement d’origine:
– Interne, provoqué par le processus lui-même:
• Involontairement: division par zéro, dépassement de capacité de la pile, …
• Volontairement: gestion d’une alarme, gestion d’E/S, …
– Externe, provoqué par :
• Le système (Noyau): fin d’E/S, …
• Un autre processus: fin d’un processus fils, …
• Un utilisateur: En utilisant le clavier (<CTRL C>>, par exemple) ou la commande kill du shell
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 39/70
Codage des signaux Génie Logiciel
USJ FI
Semestre 4

• Le SE gère un ensemble de signaux définis dans le fichier signal.h


• Chaque signal a:
– Un numéro (valeur entière), représenté par un nom symbolique
– et un traitement par défaut (handler)
• Réside en mode utilisateur (mais peut contenir appel système)

• Attention: il est important d’utiliser les noms symboliques des signaux, les
valeurs entières associées étant dépendantes de l’implémentation (ex:
SIGCHLD = 17 sous LINUX, 18 sous Solaris et 20 sous FreeBSD)

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 40/70


Liste des signaux selon le standard POSIX Génie Logiciel
USJ FI
Semestre 4

• signaux relatifs à l’arrêt de processus: • Signaux relatifs aux interactions


– SIGCHLD (17): mort du fils avec le terminal:
– SIGKILL(9): signal de terminaison – SIGHUP: terminaison du processus
– SIGSTOP : Arrêter le processus leader de session
– SIGCONT: Continue l’exécution (si arrêté) – SIGINT: envoyé si le caractère
• signaux relatifs à des erreurs: Control-C est entré au terminal.
– SIGILL (4): instruction illégale Provoque la terminaison du
– SIGFPE (8): erreur arithmétique processus
– SIGSEGV (11): violation mémoire – SIGQUIT: envoyé si le caractère
– SIGPIPE (13): écriture dans un tube sans Control-\ est entré au terminal.
lecteur provoque la terminaison du
• signaux relatifs aux temporisations: processus
– SIGALRM(14): fin de temporisation • Signaux émis par les processus
(fonction alarm) utilisateurs:
– SIGUSR1, SIGUSR2
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 41/70
Envoi d'un signal: Appel système KILL Génie Logiciel
USJ FI
Semestre 4

• Envoyer un signal à un processus


– int kill(pid_t pid, int sig)
envoie le signal sig à un processus ou à un groupe de processus:
• au processus pid si pid > 0
• au groupe du processus appelant si pid = 0
• à tous les processus si pid = -1 (non-conforme POSIX)
• au groupe du processus | pid | si pid < -1
• Exemple: kill(12563, SIGKILL)
– Pour que P1 puisse envoyer un signal à P2,
• le propriétaire effectif de P1 doit être 0 (root), ou
• le propriétaire réel ou effectif de P1 doit être le même que celui de P2.
– sig peut être :
• Soit  0 ou  NSIG Valeur incorrecte
•0 Pas de signal envoyé mais test d’existence
• Sinon Signal de numéro sig

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 42/70


Envoi d'un signal: Commande KILL Génie Logiciel
USJ FI
Semestre 4

• Utilisation de la commande kill du shell:


– kill –nom-du-signal pid
– kill –numéro-du-signal pid
• kill appelée avec l’option -l fournit la liste des noms des signaux.
$kill –l
HUP INT QUIT ILL TRAP IOT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM USR1 USR2 CLD PWR VTALRM
PROF IO WINCH STOP TSTP CONT TTIN TTOU
• Exemples:
– Envoi du signal SIGINT au processus 567
• $kill –INT 567
– Envoi du signal SIGKILL au processus 7890
• $kill –9 7890

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 43/70


Envoi d'un signal: Autres possibilités Génie Logiciel
USJ FI
Semestre 4

• Déclencher une temporisation


– int alarm(int nb_sec);
– Exemple: alarm(10)
– au bout de nb_sec unités de temps, le signal SIGALRM est envoyé au processus
– Le comportement par défaut d’un tel signal est la terminaison
– Un appel avec nb_sec = 0 annule la demande antérieure
• Attendre un signal
– int pause();
• suspend l’appelant jusqu’au prochain signal (équivalent à CTRL-Z)
– void sleep (int nbSec);
• suspend l’appelant jusqu’au prochain signal ou l’expiration du délai (délai = nbSec secondes)

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 44/70


Envoi d'un signal: Exemple Génie Logiciel
USJ FI
Semestre 4

• Dans l’exemple suivant, un processus père envoie un signal à son processus fils après
avoir testé son existence en lui adressant le signal 0.
#include <iostream>
#include <unistd.h>
#include <wait.h>
#include <signal.h>
int main( ) {
pid_t pid ;
int etat ;
if ( ( pid = fork( ) ) == 0 )
pause(); /* processus fils bouclant*/
sleep ( 10 ) ;
if( kill ( pid , 0 ) == -1 )
std::cout<< "fils "<< pid<<" inexistant\n";
else {
std::cout<< "envoi du signal SIGUSR1 au processus "<<pid<<std::endl ;
kill ( pid , SIGUSR1 ) ;
pid = wait (& etat ) ;
std::cout<< "Etat du fils "<<pid<<" : "<<etat<<std::endl ;
}
}

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 45/70


De la réception au traitement Génie Logiciel
USJ FI
Semestre 4

• Détection en mode noyau et traitement en mode utilisateur


– C’est le SE qui détecte et le processus qui réagit
• Un processus peut choisir:
– d’ignorer le signal.
– se satisfaire du traitement associé au signal par défaut.
– d’effectuer une action spécifiquement choisie, appelée traitant ou handler.
• redéfinir un traitement spécifique (si le système le permet)
• Exceptions: SIGKILL, SIGSTOP.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 46/70


Associer un traitement explicite à un signal Génie Logiciel
USJ FI
Semestre 4

• Tout processus peut installer, pour chaque type de signal (hormis SIGKILL
et SIGSTOP), un nouveau handler.
• Associer un traitement explicite à un signal
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t fct);
– définit la fonction fct (le handler) comme étant à appeler lors de la réception du
signal signum. Au retour de la fonction, le contrôle retourne à l'endroit où le
processus a été interrompu
– le traitement par défaut de SIGKILL et SIGSTOP ne peut être modifié;
– Un handler ne doit utiliser que des fonctions sûres, dites réentrantes.
• Il faut toujours se rappeler que même une affectation peut correspondre à plusieurs instructions
machines non atomique.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 47/70


Associer un traitement explicite à un signal Génie Logiciel
USJ FI
Semestre 4

• signal(sig, SIG_IGN)
permet d'ignorer le signal sig
• signal(sig, SIG_DFL)
rétablit le traitement par défaut du signal sig.
• A tout signal est associé un traitement (Handler) par défaut qui correspond
à la terminaison du processus
• Plusieurs possibilités:
– exit - Le processus se termine (avec si possible un fichier core)
– ignore - Le processus ignore le signal
– pause - Suspension du processus
– continue - Reprise du processus si il était suspendu

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 48/70


Associer un traitement explicite à un signal Génie Logiciel
USJ FI
Semestre 4

• Traitement du signal dans le contexte d’exécution du processus


• Après exécution du traitement, le processus reprend le code interrompu à
l’instruction qui suit celle exécutée avant le traitement
• NB :
– SVR4: l'appel signal( ) n'est valable que pour un seul envoi de signal (il faut réarmer
!)
– BSD: l'appel signal( ) est valable pour un nombre indéterminé d'envois du signal
– POSIX.4 remplace signal( ) par l'appel sigaction( )

Remarque: signal() n'émet pas de signal (la fonction qui émet un signal est la
fonction kill …)
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 49/70
Traitement des signaux: Exemple Génie Logiciel
USJ FI
Semestre 4

/* temporisation */
#include <iostream>
#include <unistd.h>
#include <signal.h>
constexpr auto TEMPS = 15;
void hand(int sig) {
std::cout<<"la réponse n’est pas arrivée à temps \n";
exit(0);
}

int main( ) {
int reponse;
signal(SIGALRM,hand);
std::cout<<"Question ?";
alarm(TEMPS);
std::cin>>reponse;
alarm(0);
std::cout<<"Réponse lue \n";
}

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 50/70


Signaux : synthèse Génie Logiciel
USJ FI
Semestre 4

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 51/70


Signaux : synthèse Génie Logiciel
USJ FI
Semestre 4

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 52/70


Installer un handler: Interface POSIX sigaction Génie Logiciel
USJ FI
Semestre 4

#include <signal.h>
int sigaction( int sig , struct sigaction *act , struct sigaction * old_act);
La structure sigaction a la forme suivante.
struct sigaction
{
void (* sa_handler)(int);
int sa_flags;
sigset_t sa_mask;
}
• sa_handler: un pointeur de fonction à un argument entier
– SIG_DFL: traitant par défaut.
– SIG_IGN: ignorer le signal.
– Si act.sa_handler == f, l’appel sigaction(sig,&act,&old_act) installe le traitant f() pour
le signal sig et récupère l’ancien dans old_act.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 53/70


Installer un handler: Interface POSIX sigaction Génie Logiciel
USJ FI
Semestre 4

• sa_flags peut valoir, en particulier


– SA_NOCLDSTOP et sig==SIGCHLD: ne pas générer SIGCHLD si un fils est stoppé.
– SA_NOCLDWAIT: si sig est SIGCHLD, ne pas faire passer les fils zombis.
– SA_RESTART: redémarre les appels systèmes interruptibles, interrompus avant
d’avoir pu commencer.
– SA_RESETHAND: rebascule le traitant à SIG_DFL lors de la délivrance.
– SA_NODEFER: ne pas masquer dans le handler le signal délivré.
• Le masque installé durant le handler est l’union
– du masque courant,
– du signal ayant provoqué son appel,
– de l’ensemble spécifié par sa_mask.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 54/70


Installer un handler: Interface POSIX sigaction Génie Logiciel
USJ FI
Semestre 4

• Si le contenu du champ sa_handler n’est ni SIG_IGN, ni SIG_DFL le champ


sa_mask contient une liste des signaux qui doivent être masqués (en plus
du signal lui-même) pendant la durée de l’exécution de la fonction.
• Si durant l’appel de sigaction :
– p_action = NULL, le comportement n’est pas modifié
– Si p_action_anc n’est pas NULL, au retour de la fonction on y trouve le
comportement associé au signal avant réalisation du changement.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 55/70


Installer un handler: Interface POSIX sigaction Génie Logiciel
USJ FI
Semestre 4

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 56/70


Génie Logiciel
USJ FI
Semestre 4

Partie V
Les fils d’exécution (threads)

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 57/70


Processus (Flot d’exécution Lourd) Génie Logiciel
USJ FI
Semestre 4

• Contexte volumineux
• Espace protégé
– Espace d’adressage non accessible depuis un autre processus
– Partage / échange de données
• Au moment de la création d’un processus fils: fork()
• Via des segments de mémoire partagée
• Via des messages
• Commutations coûteuses

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 58/70


Threads (Flot d’exécution Léger) Génie Logiciel
USJ FI
Semestre 4

• Fil = Flot = tâche = thread = lightweight process


• Un Thread est un flux d’instructions.
• Contexte allégé
– Une partie partagée: mémoire adressable, ressource (fichiers ouverts, …)
• lorsqu’un thread modifie une variable (non locale), tous les autres threads voient la modification.
• un fichier ouvert par un thread est accessible aux autres threads (du même processus).
– Une partie propre: pile, registres, ...
• Commutations plus rapides
• Efficacité et facilité d’écriture des applications concurrentes
– Plusieurs flots d’exécution
– Partage de données immédiat

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 59/70


Processus à un thread et à plusieurs threads Génie Logiciel
USJ FI
Semestre 4

En commun

Séparés

Mono-flot Multi-flots
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 60/70
Thread vs processus Génie Logiciel
USJ FI
Semestre 4

• Le Thread ne peut pas exister sans processus, mais il peut y avoir


plusieurs Threads par processus

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 61/70


Types de Threads Génie Logiciel
USJ FI
Semestre 4

• Threads de noyau: supportés directement par le noyau du SE (Windows,


Linux)
– les opérations sur les threads sont des appels au système
– le noyau est capable de gérer directement les états des threads
– Il peut affecter différents threads à différentes UCTs

• Threads d’utilisateur: supportés par des librairies ou par le langage de


programmation (par exemple Java)
– les opérations sur les threads ne demandent pas des appels au système
– sont gérées par le système d’exécution du langage de programmation (p.ex. Java)
– le noyau ne peut pas les gérer directement

• Approche hybride implémentant des threads niveau utilisateur et niveau


noyau (Solaris 2).
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 62/70
Threads dans l'espace utilisateur Génie Logiciel
USJ FI
Semestre 4

• Supportés par dessus le noyau, via un ensemble d’appels de bibliothèque


au niveau utilisateur.
– Code de gestion des threads dans une librairie
• Pas de modification du noyau
• Le gestionnaire de threads ainsi que les threads s’exécutent au sein d’un
processus utilisateur

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 63/70


Implémentation des threads dans l'espace utilisateur Génie Logiciel
USJ FI
Semestre 4

Système d'exécution:
logiciel procurant des
services à un programme
• Gestion de la mémoire
• Débogueur
• Threads utilisateur
• Bibliothèques partagées
• Etc.

• Rapidité: Pas de passage en mode noyau


• Contrôle: Ordonnancement adapté
• Problème: Appels systèmes bloquant, fautes de page, etc.
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 64/70
Threads dans l'espace utilisateur : Avantages et inconvénients Génie Logiciel
USJ FI
Semestre 4

• Parallélisme (-)
– Pas de parallélisme réel entre les threads d’un espace virtuel
• Efficacité (+)
– La commutation de contexte est rapide
• Appels systèmes bloquants (-)
– Le processus est bloqué au niveau du noyau
– Tous les threads sont bloqués tant que l’appel système (I/O) n’est pas terminé
– Il n’y a donc pas de multiprogrammation dans un espace virtuel

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 65/70


Threads supportés par le noyau Génie Logiciel
USJ FI
Semestre 4

• Gérés par le noyau


• Lorsqu’un thread se bloque, le noyau alloue le processeur à un autre thread
– Lorsqu'un thread est bloqué, les autres threads demeurent actifs.
• Exemples: Windows, Solaris, Linux

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 66/70


Threads supportés par le noyau : Avantages et inconvénients Génie Logiciel
USJ FI
Semestre 4

• Appels systèmes bloquants (+)


– Pas de blocage des threads d’un espace virtuel lors d’un appel système
• Parallélisme réel (+)
– N threads d’un espace virtuel peuvent s’exécuter sur K processeurs
• Efficacité (-)
– Commutation plus chère que pour les threads dans l'espace utilisateur, car demande
un passage en mode noyau.

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 67/70


Solutions hybrides permettant une commutation légère Génie Logiciel
USJ FI
Semestre 4

• Principes des threads dans l'espace utilisateur (commutations gérées au


niveau utilisateur)
• Modification du noyau pour gérer les appels systèmes de manière à ne pas
bloquer les threads
– Lorsqu’un thread fait un appel système
bloquant, le noyau ne préempte pas le
processus.
– Un mécanisme de signaux permet de
gérer la fin de l’appel bloquant.
– L’ordonnanceur est départagé entre
l’espace système et l’espace utilisateur
(ordonnanceurs coopérants).

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 68/70


Autres solutions hybrides permettant un parallélisme réel Génie Logiciel
USJ FI
Semestre 4

• Principes des threads supportés par le noyau (parallélisme réel possible)


• Principes des threads dans l'espace utilisateur (commutations légères)
– On peut associer plusieurs
threads dans l'espace utilisateur
à un thread supporté par le
noyau
– Appels systèmes bloquants
gérés ou non par le système

Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 69/70


Exemple : Threads en C++ Génie Logiciel
USJ FI
Semestre 4

#include <iostream>
#include <thread>
#include <vector>
#include <algorithm>

void threadFunction (std::vector<int> &speeds, int start, int end, int& res) {
std::cout << "starting thread ... " << std::endl;
for (int i = start; i <= end; ++i)
res += speeds[i];
std::cout << "end thread ... " << std::endl;
}

int main() {
std::vector<int> speeds (100000);
std::generate(begin(speeds), end(speeds), [] (){ return rand() % 10 ; });
int th1Result = 0, th2Result = 0;
std::thread t1 (threadFunction, std::ref(speeds), 0, 49999, std::ref(th1Result));
std::thread t2 (threadFunction, std::ref(speeds), 50000, 99999, std::ref(th2Result));
t1.join();
t2.join();
std::cout << "Result = " << th1Result + th2Result << std::endl;
return 0;
}
Systèmes d'exploitation 02- Les processus Maroun CHAMOUN E S I B 70/70

Vous aimerez peut-être aussi