0% ont trouvé ce document utile (0 vote)
9 vues182 pages

Gestion des processus et threads OS

Processus-Threads

Transféré par

fenniyasmine8
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
9 vues182 pages

Gestion des processus et threads OS

Processus-Threads

Transféré par

fenniyasmine8
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Contexte

Du programme au processus
Gestion des processus par l’OS
Processus
Threads

Processus et threads
ASR période 3

Sylvain Jubertie
[Link]@[Link]

1 / 182
Contexte
Du programme au processus
Gestion des processus par l’OS
Processus
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

2 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

3 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

4 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Terminologie

Programme
Un programme est un fichier source écrit dans un langage donné,
par exemple un programme C, C++, ou Java.

Programme exécutable, binaire


Un programme désigne également le fichier en langage binaire
obtenu après compilation, on parle également de programme
exécutable ou de binaire.

Processus
Un processus est un programme binaire en cours exécution par le
système d’exploitation.
5 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Qu’est-ce qu’un processus ?

Definition
Un processus est constitué d’un programme binaire : instructions +
données statiques, associé à un contexte d’exécution :
pile + tas
données dans les registres du processeur
instruction courante

6 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

7 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Systèmes d’exploitation

Point de vue de l’OS

L’OS est chargé du lancement des processus.


L’OS attribue à chaque processus un identifiant nommé pid
(process id).
L’OS attribue un environnement mémoire au processus.
L’OS contrôle l’exécution d’un processus, il peut
l’interrompre, l’arrêter, le faire continuer, etc.
Un OS multitâche est capable d’entrelacer l’exécution de ses
processus en fonction de priorités (scheduling, préemption,
commutation de contexte). On peut donc exécuter plusieurs
processus sur un même processeur.

8 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

9 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Architectures actuelles

Multi-processeurs
Plusieurs processeurs sont présents sur une même carte mère.

10 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Architectures actuelles

Multi-coeurs
Chaque processeur contient plusieurs coeurs qui peuvent partager
du cache.

11 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Architectures actuelles

Hyper-threading (SMT)
Le processeur physique comporte plusieurs processeurs logiques
chacun disposant de ses propres registres mais le pipeline, le cache
et le bus sont partagés.

12 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

13 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Enjeux

Multitâche
Effectuer plusieurs tâches sur une machine !
Utilisation bureautique : écouter de la musique en surfant sur
le web, . . .
Utilisation serveur : Gérer plusieurs serveurs sur une machine,
plusieurs machines virtuelles, . . .

14 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Enjeux

Performance
Répartir les calculs sur plusieurs processeurs pour augmenter les
performances.

Performance
Il est de plus en plus difficile d’augmenter la fréquence des
processeurs (limite physique et coût). L’augmentation des
performances passe donc aujourd’hui par l’utilisation de plusieurs
processeurs.

15 / 182
Contexte
Terminologie
Du programme au processus
Systèmes d’exploitation
Gestion des processus par l’OS
Architectures
Processus
Enjeux
Threads

Enjeux

16 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

17 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

18 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Construction d’un programme exécutable


cf. TD Architecture : Processus de compilation.

19 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Organisation
Un processus est constitué de plusieurs segments :
text : contient le code exécutable et les constantes
data : contient les variables statiques et globales :
initialisées (DATA)
non initialisées (BSS : Block Started by Symbol)

20 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

BSS

DATA
programme

text

21 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Exemple hello1.c
#i n c l u d e < s t d i o . h>
i n t main ( ) {
p r i n t f ( ” H e l l o World \n” ) ;
return 0;
}

size hello1

text data bss dec hex filename


882 264 8 1154 482 hello1

22 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Exemple hello2.c
#i n c l u d e < s t d i o . h>
i n t main ( ) {
p r i n t f ( ” H e l l o World ! \ n” ) ;
return 0;
}

size hello2

text data bss dec hex filename


883 264 8 1155 483 hello2

23 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Conclusion
Les chaı̂nes constantes sont stockées dans le segment avec le code
dans le segment text !

Autres variables
Où sont stockées les autres variables ?

24 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Exemple hello3.c
#i n c l u d e < s t d i o . h>
int i ;
i n t main ( ) {
p r i n t f ( ” H e l l o World ! \ n” ) ;
return 0;
}

size hello3

text data bss dec hex filename


883 264 12 1159 487 hello3

25 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Exemple hello4.c
#i n c l u d e < s t d i o . h>
i n t i =5;
i n t main ( ) {
p r i n t f ( ” H e l l o World ! \ n” ) ;
return 0;
}

size hello4

text data bss dec hex filename


883 268 8 1159 487 hello4

26 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Conclusion
Les variables globales sont stockées dans les segments :
DATA si elles sont initialisées
BSS si elles ne sont pas initialisées
Remarque : les variables initialisées explicitement à 0 sont
considérées comme non initialisées.

27 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Exemple hello5.c
#i n c l u d e < s t d i o . h>
c o n s t i n t i =5;
i n t main ( ) {
p r i n t f ( ” H e l l o World ! \ n” ) ;
return 0;
}

size hello5

text data bss dec hex filename


887 264 8 1159 487 hello4

28 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Conclusion
Les constantes même définies comme des variables sont stockées
dans le segment text !

29 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

Exemple prog1.c
i n t var1 = 9 , var2 = 0 , var3 ;
const i n t var4 = 5;
i n t main ( ) {
i n t var5 ;
}

30 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

objdump -x prog1 | grep var

08048460 g O .rodata 00000004 var4


0804a010 g O .data 00000004 var1
0804a01c g O .bss 00000004 var2
0804a020 g O .bss 00000004 var3

31 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Programme exécutable

var5 ? ? ?
Mais où est passée var5 ?

32 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

33 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Chargement du programme en mémoire

Objectif
Placer le programme exécutable, stocké sur le disque, dans la
mémoire physique pour l’exécuter. Le chargeur de l’OS doit
également ajouter des segments pour gérer entre autre la pile et le
tas.

Mémoire réelle
La mémoire réelle, ou physique, correspond à la quantité de
mémoire installée sur le système. Elle peut être vue comme un
tableau d’octets.

34 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Chargement du programme en mémoire

Attention !
Sous Linux le processus ne s’exécute pas en mémoire réelle mais
en mémoire virtuelle.

35 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Chargement du programme en mémoire

Mémoire virtuelle et pagination

Sous Linux, tous les programmes s’exécutent en mémoire


virtuelle et leurs segments sont placés au chargement dans des
pages de la mémoire virtuelle.
Les pages en mémoire virtuelle sont mises en correspondance
avec les pages de mémoire réelle, appelées également cases,
par une table des pages propre à chaque processus.
Ce processus est implicite et est effectué par l’OS.
Sous Linux la taille d’une page est de 4KO.

36 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Chargement du programme en mémoire

Avantages sur la mémoire réelle

Abstraction de l’implantation mémoire.


Pas d’accès direct à la mémoire réelle : protection par
l’intermédiaire de l’OS.
Partage simplifié de la mémoire réelle par plusieurs
programmes.
Optimisation de l’utilisation mémoire : les pages du processus
en cours d’exécution sont dans la mémoire centrale.
Possibilité d’utiliser un espace swap.
Espace d’adressage jusqu’à 3GO par processus pour les OS
32bits !

37 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Chargement du programme en mémoire

Processus de chargement

1 Diviser le programme en pages


2 Passage d’un adressage linéaire à un adressage en mémoire
virtuelle.
3 Vérification de la disponibilité de cases en mémoire réelle.
4 Chargement des pages utilisées dans les cases disponibles.

38 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Chargement du programme en mémoire

Table des cases


La table des cases contient des informations sur l’état des cases en
mémoire réelle :
soit vide,
soit le numéro du processus et de la page de ce dernier
stockée dans la case.

39 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Chargement du programme en mémoire

Table des pages d’un processus


La table des pages d’un processus contient les champs suivants :
le numéro de la page
la date de chargement de la page,
la date de dernier accès ;
un bit indiquant si la page est présente en mémoire réelle,
un bit indiquant si la page a été modifiée en mémoire réelle.
le numéro de case physique le cas échéant.

40 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Chargement du programme en mémoire

mémoire réelle

8
processus
#page #case 7
P4 P3 6
P4 3
P3 5
P3 6
P2 4
P2 1
P1 P4 3
P1 2
tables des pages P1 2
P2 1

41 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

42 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Processus en mémoire

Segmentation
Un processus est constitué de plusieurs segments :
text : contient le code exécutable et les constantes
data : contient les variables statiques et globales :
initialisées (DATA)
non initialisées (BSS : Block Started by Symbol)
ainsi que le heap (tas) pour les données alouées
dynamiquement (malloc en C)
stack (pile) : contient les variables locales

43 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Processus en mémoire
adresse haute

stack

heap
espace
BSS d'adressage

DATA

text

adresse basse

44 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Processus en mémoire

Evolution de la taille du processus en mémoire

les segments text, DATA et BSS ont une taille constante en


mémoire. Visualisation de la taille des segments text, DATA
et BSS par la commande : size progname
la taille du segment heap évolue en fonction des allocations
dynamiques effectuées (new & malloc)
la taille du segment stack évolue en fonction de l’appel aux
fonctions et des variables locales contenues dans ces fonctions.

45 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Processus en mémoire

Segments et pages

Un segment est une zone contiguë de la mémoire virtuelle qui


peut être partagée et protégée : notion de droits.
Un segment est divisé en pages de 4KO.
Visualisation des segments d’un processus en mémoire
virtuelle par la commande : cat /proc/pid/maps

46 / 182
Contexte
Du programme au processus Programme exécutable
Gestion des processus par l’OS Chargement du programme en mémoire
Processus Processus en mémoire
Threads

Processus en mémoire

démo

47 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

48 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Introduction

Services fournis par l’OS

Informations sur les processus


Etats des processus
Contrôle des processus
Ordonnancement

49 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

50 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Informations
ps

liste des processus


propriétaire de chaque processus
pid et parent pid des processus
...

Utilisation

-e : tous les processus


axjf : arborescence des processus
-u username : processus d’un utilisateur
Plus d’options avec man ps !
51 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

52 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Etats des processus

top ou htop

running
sleeping
stopped
zombie !

53 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

54 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Signaux

kill

KILL
CONT
STOP
...
man kill pour plus d’infos.

Exemple
kill -9 -1 : supprime tous les processus possibles (en fonction
des droits).

55 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

56 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Scheduling

Ordonnanceur (Scheduler)

Partie de l’OS chargée du contrôle de l’exécution des


processus.
Sur un système monoprocesseur, un seul processus peut être
exécuté à un instant donné
Sur un système à N processeurs, N processus peuvent être
exécutés simultanément
Notion de priorité : certains processus sont plus prioritaires
que d’autres
Notion d’affinité : le scheduler choisit le processeur sur lequel
exécuter un processus

57 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Scheduling

Principe

Structure de données contenant les identifiants les processus


et des informations sur ceux-ci (Tableau de listes de processus
classé par priorité).
Le scheduler commence par exécuter les processus de la liste
de plus haute priorité, puis passe à la liste suivante.
Une fois tous les processus traités, le scheduler recommence le
traitement.
Plus un processus est prioritaire, plus le scheduler lui attribue
du temps d’exécution.

58 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Scheduling

Priorité
La priorité d’un processus peut être déterminée de 2 manières :
par le scheduler, qui “observe” chaque processus
par l’utilisateur via la commande nice

59 / 182
Contexte Introduction
Du programme au processus Informations
Gestion des processus par l’OS Etats des processus
Processus Signaux
Threads Ordonnancement(Scheduling)

Scheduling

nice

-20, priorité la plus favorable à 19.


Par défaut priorité à 10

60 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

61 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Introduction

Au commencement. . .

un seul processus init


init lance d’autres processus et ainsi de suite
les processus forment ainsi une arborescence
chaque processus possède ainsi un processus père

Destruction du père
Un processus dont le père est détruit est “adopté” par le processus
init

62 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Introduction

Héritage
Chaque processus possède les informations suivantes :
son identifiant pid
l’identifiant de son processus père ppid
un propriétaire
un héritage de l’environnement du processus père

63 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

64 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Création

fork

La création d’un processus est effectuée par l’appel à la


méthode : pid t fork ()
Cet appel provoque la création d’une copie du processus père
(mémoire virtuelle).
Les processus père et fils ne diffèrent que par la valeur de
retour de la fonction fork.
Tous les processus, sauf init, sont créés par des appels à
fork.
Les processus père et fils continuent leur exécution juste après
l’appel à fork.

65 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Création

Valeurs de retour pour fork

-1 : si le processus ne peut être “forké”


0 : pour le processus fils
pid du fils : pour le processus père

Différenciation
On utilise la valeur de retour de fork pour différencier les
processus père et fils.

66 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Création

pid et ppid

pid t getpid () : récupération du pid


pid t getppid() : récupération du ppid

67 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Création
#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>

i n t main ( ) {

char c ;
pid t ret = fork ();
i f ( ret ) {
p r i n t f ( ” P r o c e s s u s %d p e r e du p r o c e s s u s %d\n” ,
getpid () , ret );
}
else {
p r i n t f ( ” P r o c e s s u s %d f i l s du p r o c e s s u s %d\n” ,
getpid () , getppid ( ) ) ;
}
s c a n f ( ”%c ” , &c ) ;
return 0;

68 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Création

Exécution d’un code différent

L’appel à fork provoque la duplication du code du processus


père pour la création du processus fils.
On souhaite créer un processus fils disposant d’un code
différent de celui du processus père.

69 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Création

Famille de fonction exec()

int execl (const char ∗path, const char ∗arg, ...);

int execlp (const char ∗ file , const char ∗arg, ...);

i n t e x e c l e ( c o n s t c h a r ∗ path , c o n s t c h a r ∗ a r g ,
. . . , c h a r ∗ c o n s t envp [ ] ) ;

int execv(const char ∗path, char ∗const argv []);

int execvp(const char ∗ file , char ∗const argv []);

70 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Création

#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>
i n t main ( ) {
char c ;
pid t ret = fork ();
i f ( ret ) {
p r i n t f ( ” P r o c . %d p e r e du p r o c . %d\n” , g e t p i d ( ) , r e t ) ;
wait ( ) ;
}
else {
p r i n t f ( ” P r o c . %d f i l s du p r o c . %d\n” , g e t p i d ( ) , g e t p p i d ( ) ) ;
e x e c l ( ” / b i n / l s ” , ” l s ” , ”− l ” , NULL ) ;
p r i n t f ( ” E r r e u r a p p e l e x e c l \n” ) ;
}
return 0;
}

71 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Création

Remarques

L’appel à exec provoque le remplacement du code pour le


processus fils par celui du programme appelé.
Le code du processus fils placé après l’appel à exec n’est donc
jamais exécuté sauf si l’appel à exec échoue.

72 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Création

Ordre d’exécution

Les codes du processus père et des processus fils ne sont plus


exécutés dans l’ordre d’écriture.
Un même code peut être exécuté par plusieurs processus.
L’exécution des processus est entrelacée par le scheduler,
l’exécution d’un même programme peut donc provoquer des
affichages/résultats différents.

Section suivante...
Besoin de synchronisation !

73 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

74 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Attente de processus fils


3 fonctions sont à disposition pour surveiller le changement d’état
de processus fils (terminaison, pause, continuation) :
pid t wait( int ∗ status )

pid t waitpid ( pid t pid , int ∗status , int options )

p i d t w a i t i d ( i d t y p e t idtype , i d t id ,
s i g i n f o t ∗ infop , int options )

75 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Sans appel à wait


2 cas possibles si aucune synchronisation entre le processus père et
les processus fils :
1 le processus père se termine avant ses processus fils
2 le(s) processus fils se termine(nt) avant le processus père

76 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

cas 1 : adoption
Si un processus père se termine avant ses processus fils, ceux-ci
sont adopter par le processus init.

Observation
ps −edf : processus adoptés ont un ppid dont la valeur passe à 1
après la terminaison du père.

77 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation
#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>

i n t main ( ) {

char c ;
pid t ret = fork ();
i f ( ret ) {
p r i n t f ( ” P r o c e s s u s %d p e r e du p r o c e s s u s %d\n” ,
getpid () , ret );
sleep (10);
}
else {
p r i n t f ( ” P r o c e s s u s %d f i l s du p r o c e s s u s %d\n” ,
getpid () , getppid ( ) ) ;
sleep (20);
}
return 0;

}
78 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

cas 2 : processus Zombie


Si un processus fils n’est pas attendu il reste en état zombie :
jusqu’à la fin du processus père si aucun wait du père,
ou jusqu’à un appel à wait du père récupérant la fin du
processus fils.

Observation
ps aux : processus zombies identifiés par Z+

79 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation
#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>

i n t main ( ) {

char c ;
pid t ret = fork ();
i f ( ret ) {
p r i n t f ( ” P r o c e s s u s %d p e r e du p r o c e s s u s %d\n” ,
getpid () , ret );
sleep (10);
}
else {
p r i n t f ( ” P r o c e s s u s %d f i l s du p r o c e s s u s %d\n” ,
getpid () , getppid ( ) ) ;
}
return 0;

80 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Remarques sur la synchronisation

Ne jamais se baser sur des a priori concernant l’ordre


d’exécution des processus.
L’appel à sleep ne doit jamais être utilisé pour synchroniser
des processus.
La synchronisation doit se faire à l’aide de fonctions de
synchronisation adéquates comme wait.

81 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Avec wait

L’appel à wait est effectué par le processus père.


wait provoque une attente par le processus père de la
terminaison d’un processus fils.
Pour attendre n processus fils il faut n appels à wait.

82 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation
#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>

i n t main ( ) {

char c ;
pid t ret = fork ();
i f ( ret ) {
p r i n t f ( ” P r o c e s s u s %d p e r e du p r o c e s s u s %d\n” ,
getpid () , ret );
w a i t ( ) ; // a t t e n t e du p r o c e s s u s f i l s .
}
else {
p r i n t f ( ” P r o c e s s u s %d f i l s du p r o c e s s u s %d\n” ,
getpid () , getppid ( ) ) ;
s c a n f ( ”%s ” , &c ) ;
}
return 0;

}
83 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation
#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>
i n t main ( ) {
char c ;
pid t ret = fork ();
i f ( ret ) {
p r i n t f ( ” P r o c . %d p e r e du p r o c . %d\n” , g e t p i d ( ) , r e t ) ;
pid t ret2 = fork ();
i f ( ret2 ) {
p r i n t f ( ” J e s u i s l e p e r e \n” ) ;
w a i t ( ) ; w a i t ( ) ; // 2 a p p e l s a w a i t
}
e l s e { p r i n t f ( ” J e s u i s l e 2eme f i l s ” ) ; }
}
else {
p r i n t f ( ” P r o c . %d f i l s du p r o c . %d\n” , g e t p i d ( ) , g e t p p i d ( ) ) ;
s c a n f ( ”%s ” , &c ) ;
}
return 0;
}
84 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Remarques

Un appel à wait récupère la terminaison d’un des processus


fils.
Si plusieurs processus fils sont terminés, le système en choisi
un arbitrairement.

Ordre de terminaison

Dans de nombreux cas l’ordre de terminaison importe !


Utilisation de pid t waitpid ( pid t pid , int ∗status , int options )

85 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Appel à waitpid
Passage d’un paramètre pid permettant de spécifier le processus
fils à attendre :
< -1 Attente d’un processus fils dont le groupid est -pid
(voir setpgid()).
-1 Attente d’un processus fils (semblable à wait).
0 Attente d’un processus fils du même groupe que le
processus père.
> 0 Attente du processus fils pid.

86 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation
#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>
i n t main ( ) {
char c ;
pid t ret = fork ();
i f ( ret ) {
p r i n t f ( ” P r o c . %d p e r e du p r o c . %d\n” , g e t p i d ( ) , r e t ) ;
pid t ret2 = fork ();
i f ( ret2 ) {
p r i n t f ( ” J e s u i s l e p e r e \n” ) ;
waitpid ( ret ); waitpid ( ret2 ); // 2 a p p e l s a w a i t
}
e l s e { p r i n t f ( ” J e s u i s l e 2eme f i l s ”); }
}
else {
p r i n t f ( ” P r o c . %d f i l s du p r o c . %d\n” , g e t p i d ( ) , g e t p p i d ( ) ) ;
s c a n f ( ”%s ” , &c ) ;
}
return 0;
}
87 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Retour du statut des processus fils


Les fonctions wait et waitpid permettent au processus père de
récupérer le statut d’un processus fils.

Côté processus fils


void exit ( int status )

Côté processus père


int status ;
w a i t (& s t a t u s ) ;

88 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Traitement de la valeur retour status


La valeur status peut être traitée par les fonctions suivantes :
WIFEXITED(status) : vrai si le processus fils s’est terminé
normalement
WEXITSTATUS(status) : code retour passé à exit
D’autres fonctions sont disponibles pour traiter les cas ou l’état du
processus fils est modifié par des signaux : man wait.

89 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation
#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <s y s / t y p e s . h>
#i n c l u d e <s y s / w a i t . h>

i n t main ( ) {
i n t r e s =0;
pid t ret = fork ();
i f ( ret ) {
p r i n t f ( ” P r o c e s s u s p e r e \n” ) ;
w a i t (& r e s ) ;
p r i n t f ( ” V a l e u r r e n v p a r f i l s = %d\n” , WEXITSTATUS( r e s ) ) ;
}
else {
p r i n t f ( ” P r o c e s s u s f i l s \n” ) ;
exit (12);
}
return 0;
}
90 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Les signaux
Les signaux sont des interruptions logicielles à destination d’un
processus, par exemple pour signaler une erreur. Le processus
recevant un signal possède une fonction pour traiter celui-ci.
Ce système de signaux peut être détourné pour effectuer des
synchronisations entre plusieurs processus en écrivant ses propres
fonctions.

91 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Envoi d’un signal


L’envoi de signaux :
au processus courant s’effectue par la fonction raise
à un autre processus est effectué par la fonction kill
int kill ( pid t pid , int sig )

pid : identifiant du processus destinataire


sig : type de signal à envoyer

92 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Types de signaux
Les signaux sont numérotés de 0 à 31, quelques exemples :
SIGHUP 1 : hangup
SIGINT 2 : interruption
SIGQUIT 3 : quit
SIGILL 4 : instruction illégale
SIGKILL 9 : hard kill
SIGALRM 14 : alarme
SIGCONT 19 : continuation d’un processus
SIGCHLD 20 : vers le processus parent lorsqu’un processus fils
s’arrête
93 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>
#i n c l u d e < s i g n a l . h>

i n t main ( ) {
char c ;
pid t ret = fork ();
i f ( r e t ) { // S e c t i o n du p r o c e s s u s p a r e n t
s c a n f ( ”%c ” , &c ) ;
k i l l ( r e t , SIGKILL ) ; // E n v o i du s i g n a l SIGKILL
sleep (10);
}
e l s e { // S e c t i o n du p r o c e s s u s f i l s
w h i l e ( 1 ) ; // A t t e n t e a c t i v e
}
return 0;
}

94 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Attente active (polling)


Le processus en attente du signal reste actif mais ne fait rien dans
l’attente d’un signal. Cette technique n’est pas efficace car elle
consomme des ressources processeur inutilement.

Attente passive
Il est possible de mettre un processus en sommeil dans l’attente
d’un signal à l’aide de la fonction pause.
int pause()

95 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>
#i n c l u d e < s i g n a l . h>

i n t main ( ) {
char c ;
pid t ret = fork ();
i f ( ret ) {
s c a n f ( ”%c ” , &c ) ;
k i l l ( r e t , SIGKILL ) ;
sleep (10);
}
else {
pause ( ) ;
}
return 0;
}

96 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Autre exemple : Contrôle du processus fils


Mise en pause et relance du processus fils à l’aide, respectivement,
des signaux SIGSTOP et SIGCONT.

97 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation
#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>
#i n c l u d e < s i g n a l . h>

i n t main ( ) {
char c ;
pid t ret = fork ();
i f ( ret ) {
sleep (10);
k i l l ( r e t , SIGSTOP ) ;
sleep (10);
k i l l ( r e t , SIGCONT ) ;
sleep (10);
k i l l ( r e t , SIGKILL ) ;
}
else {
while (1);
}
return 0;
}
98 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Réception d’un signal et traitement


Il est possible de spécifier sa propre fonction à exécuter lors de la
réception d’un signal à l’aide de la fonction signal.
signal ( sig , void (∗func )())

sig : signal à traiter


void (*func)() : pointeur vers la fonction de traitement

99 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation

Pointeur sur fonction : déclaration


typeretour (∗nompointeur)(arguments)

Pointeur sur fonction : appel


(∗nomdupointeur)(arguments)

100 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation
#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>
#i n c l u d e < s i g n a l . h>

v o i d o n i n t ( ) { p r i n t f ( ”INTERRUPTION RECUE\n” ) ; }

i n t main ( ) {
char c ;
pid t ret = fork ();
i f ( ret ) {
s c a n f ( ”%c ” , &c ) ;
k i l l ( r e t , SIGINT ) ;
sleep (10);
}
else {
s i g n a l ( SIGINT , o n i n t ) ;
pause ( ) ;
}
return 0;
}
101 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Synchronisation
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e < s i g n a l . h>
v o i d o n i n t ( ) { s i g n a l ( SIGINT , o n i n t ) ; p r i n t f ( ”INT\n” ) ; }
v o i d o n q u i t ( ) { p r i n t f ( ”QUIT\n” ) ; e x i t ( 0 ) ; }

i n t main ( ) {
char c ;
pid t ret = fork ();
i f ( ret ) {
s c a n f ( ”%c ” , &c ) ;
switch ( c ) {
c a s e ’ i ’ : k i l l ( r e t , SIGINT ) ; b r e a k ;
c a s e ’ q ’ : k i l l ( r e t , SIGQUIT ) ; b r e a k ; }
sleep (5);}
else {
s i g n a l ( SIGINT , o n i n t ) ;
s i g n a l ( SIGQUIT , o n q u i t ) ;
pause ( ) ; }
return 0;
} 102 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

103 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication

Statut
Utilisation de la valeur de retour pour communiquer entre le
processus père et les processus fils.

Limitations
On ne peut récupérer qu’un octet !

104 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication

Moyens à dispositions

Fichiers
Pipes
Messages
Mémoire partagée
Sockets
...

105 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Fichiers

Communication par les fichiers


Utilisation de fichiers pour faire communiquer des processus.

106 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Fichiers

Rédacteur/Lecteur

Le processus fils écrit dans un fichier


Le processus père lit dans le même fichier

107 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Fichiers


#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>

i n t main ( ) {
pid t pid ;
int status ;
char b u f f e r [ 1 0 ] ;
FILE ∗ f i l e = f o p e n ( ” t e s t ” , ”w+” ) ;
i f ( fork ()) {
wait ( ) ;
f s e e k ( f i l e , 0 , SEEK SET ) ;
f r e a d ( b u f f e r , 1 , 10 , f i l e ) ;
p r i n t f ( ”%s ” , b u f f e r ) ;
fclose ( f i l e );
}
else
f w r i t e ( ” H e l l o ! \ n” , 1 , 7 , f i l e ) ;
return 0;
}

108 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Fichiers

Type
FILE* : pointeur sur un fichier

Fonctions

FILE* fopen("cheminverslefichier",
"r|r+|w|w+|a|a+")
int fseek(FILE*, offset, SEEK {SET|CUR|END})
int fclose(FILE*)

109 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Fichiers

Inconvénients

Pas très efficace : accès disque


Pas très sûr : accès concurrents

110 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Pipes

Pipes
Idée : Utiliser le système de pipe pour faire communiquer les
processus.

Rappels
ls | sort

111 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Pipes

Fonctions

popen
pipe

112 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Pipes

popen
FILE* popen("command", "r|w")
1 lance la commande dans un processus
2 crée un pipe et retourne un pointeur vers celui-ci
3 lit ou écrit à partir du pointeur

pclose
int pclose(FILE*)
1 attente de la fin du processus associé
2 retourne le statut du processus

113 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Pipes


#i n c l u d e < s t d i o . h>

i n t main ( ) {

FILE ∗ f i l e ;
char b u f f e r [ 1 0 ] ;

f i l e = popen ( ” d a t e ” , ” r ” ) ;

while ( f g e t s ( b u f f e r , 10 , f i l e ) ) {
p r i n t f ( ”%s ” , b u f f e r ) ;
}

pclose ( f i l e );

return 0;

114 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Pipes

pipe
Idée : créer 2 canaux de communication unidirectionnels entre 2
processus.

P1 P2

115 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Pipes

Fonctions

1 int pipe(int[2])
2 ssize t write(int, const void*, size t)
ssize t read(int, void*, size t)
3 int close(int)

116 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Pipes


#i n c l u d e < s t d i o . h>

i n t main ( ) {
int pipes [ 2 ] ;
pipe ( pipes ) ;
char b u f f e r [ 1 0 ] ;
i f ( fork ()) {
close ( pipes [ 1 ] ) ;
while ( read ( pipes [ 0 ] , buffer , 10))
p r i n t f ( ”%s ” , b u f f e r ) ;
close ( pipes [ 0 ] ) ;
}
else {
close ( pipes [ 0 ] ) ;
w r i t e ( p i p e s [ 1 ] , ” H e l l o ! \ n” , 7 ) ;
close ( pipes [ 1 ] ) ;
}
return 0;
}

117 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Pipes


#i n c l u d e < s t d i o . h>

i n t main ( ) {
int pipes [ 2 ] ;
pipe ( pipes ) ;
int i = 0;
i f ( fork ()) {
close ( pipes [ 1 ] ) ;
r e a d ( p i p e s [ 0 ] , &i , 4 ) ;
p r i n t f ( ”%i \n” , i ) ;
close ( pipes [ 0 ] ) ;
}
else {
i = 5;
close ( pipes [ 0 ] ) ;
w r i t e ( p i p e s [ 1 ] , &i , 4 ) ;
close ( pipes [ 1 ] ) ;
}
return 0;
}
118 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Messages

Files de messages
Passage de messages entre processus par un système de files de
messages.

119 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Messages

Fonctions

mqd t mq open(const char* name, int oflag, {mode t


mode, struct mq attr *attr})
mqd t mq send(mqd t mqdes, const char* msg ptr,
size t msg len, unsigned msg prio)
ssize t mq receive(mqd t mqdes, char* msg ptr,
size t msg len, unsigned* msg prio)
mqd t mq close(mqd t mqdes)

120 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Messages

#i n c l u d e < s t d i o . h>
#i n c l u d e <mqueue . h>
#i n c l u d e < f c n t l . h>
#i n c l u d e <s y s / s t a t . h>
i n t main ( ) {
mqd t mq ;
mq = mq open ( ” /mq5” , O CREAT | O RDWR, 0 6 0 0 , NULL ) ;
mq send (mq , ” abcd ” , 4 , 0 ) ;
return 0;
}

121 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Messages

#i n c l u d e < s t d i o . h>
#i n c l u d e <mqueue . h>
#i n c l u d e < f c n t l . h>
#i n c l u d e <s y s / s t a t . h>
#i n c l u d e < s t d l i b . h>
i n t main ( ) {
mqd t mq ;
void ∗ b u f f e r ;
struct mq attr a t t r ;
mq = mq open ( ” /mq5” , O RDONLY ) ;
m q g e t a t t r (mq , &a t t r ) ;
b u f f e r = malloc ( a t t r . mq msgsize ) ;
m q r e c e i v e (mq , b u f f e r , a t t r . m q m s g s i z e , NULL ) ;
p r i n t f ( ”%s ” , ( c h a r ∗ ) b u f f e r ) ;
return 0;
}

122 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Messages


#i n c l u d e < s t d i o . h>
#i n c l u d e <mqueue . h>
#i n c l u d e < f c n t l . h>
#i n c l u d e <s y s / s t a t . h>
#i n c l u d e < s t d l i b . h>
i n t main ( ) {
mqd t mq ;
void ∗ b u f f e r ;
struct mq attr a t t r ;
mq = mq open ( ” /mq5” , O CREAT | O RDWR, 0 6 0 0 , NULL ) ;
i f ( fork ())
mq send (mq , ” abcd ” , 4 , 0 ) ;
else {
m q g e t a t t r (mq , &a t t r ) ;
b u f f e r = malloc ( a t t r . mq msgsize ) ;
m q r e c e i v e (mq , b u f f e r , a t t r . m q m s g s i z e , NULL ) ;
p r i n t f ( ”%s \n” , ( c h a r ∗ ) b u f f e r ) ;
}
return 0;
}
123 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Mémoire partagée

Mémoire partagée
Créer un bloc de mémoire du processus père et le marquer comme
accessible par ses processus fils. A l’appel de fork(), ce bloc ne
sera pas dupliqué mais commun aux processus.

124 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Mémoire partagée

mmap
void* mmap(void* addr, size t length, int prot, int
flags, int fd, off t offset)
1 addr : adresse de début du segment de mémoire partagée
2 length : longueur du segment souhaité
3 prot : protection de l’accès (lecture, écriture, ...)
4 flags : type de segment (voir man)
5 fd : descripteur de fichier
6 offset : offset dans le fichier pour l’initialisation des données

retourne un pointeur vers le début du segment partagé

125 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Mémoire partagée

munmap
int munmap(void* addr, size t length)
Supprime le partage du segment passé en paramètre.

126 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Mémoire partagée


#i n c l u d e < s t d i o . h>
#i n c l u d e <u n i s t d . h>
#i n c l u d e <s y s /mman . h>
i n t main ( ) {
pid t res ;
i n t ∗ mem = 0 ;
mem = ( i n t ∗ )mmap(NULL , 4 , PROT READ | PROT WRITE ,
MAP SHARED | MAP ANONYMOUS, −1, 0 ) ;
i f (mem) {
res = fork ();
i f ( res ) {
wait ( ) ;
p r i n t f ( ”%i \n” , ∗mem ) ;
munmap (NULL , 4 ) ;
}
else
∗mem = 6 ;
}
return 0;
}
127 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Synchronisation
Processus
Communication
Threads

Processus : Communication : Sockets

Sockets
Etablir des communications point-à-point entre plusieurs processus.
Utilisation des sockets en période 4...

128 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

129 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Introduction

Rappels sur les processus

La création d’un nouveau processus implique la duplication de


l’espace d’adressage.
Les processus sont indépendants : données + pile d’exécution.
Un seul fil d’exécution.

130 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Introduction

Limitations

1 Pas de partage des informations simples (tubes, fichiers,


mémoire partagée, réseau, . . . ).
2 Découpage d’un programme en plusieurs processus “gros
grain”.
3 Commutation entre les processus coûteuse.

131 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Introduction

Threads

Processus “légers” partageant l’espace d’adressage du


processus père.
Un fil d’exécution par thread.

132 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Introduction

Un thread

1 1 compteur d’instruction propre.


2 1 pile d’exécution propre : variables locales privées.

133 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Introduction
Avantages

Commutation plus simple : mise à jour du compteur


d’instruction + pointeurs sur pile d’exécution.
Communication plus simple par accès à l’espace d’adressage
partagée.
Découpage des tâches à “grain fin”.

Inconvénients

Accès concurrents aux données partagées.


Problèmes de terminaison.
Problèmes d’interblocages.
134 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Introduction

Programmation sous Linux

Utilisation de la bibliothèque POSIX pthread.


POSIX : Portable Operating System Interface for LinuX,
ensemble de standards des systèmes UNIX.

135 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Introduction

Header
#include <pthread.h>

Compilation
gcc -o ... -pthread

136 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

137 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

Structure
pthread t thread

Création
int p t h r e a d c r e a t e ( pthread t ∗ thread ,
pthread attr t ∗ attr ,
void ∗ (∗ s t a r t r o u t i n e ) ( void ∗) ,
void ∗ arg ) ;

138 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

Arguments

1 pthread t∗ thread : pointeur sur le thread


2 pthread attr t ∗ attr : pointeur sur attributs
3 void∗ (∗ start routine )(void∗) : pointeur sur la fonction à exécuter
par le thread
4 void∗ arg : pointeur sur arguments de la fonction à exécuter

Valeur retournée

0 en cas de succès, id du nouveau thread dans thread.


code erreur EAGAIN, pas assez de ressources.

139 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

#i n c l u d e < s t d i o . h>

void f c t () {
p r i n t f ( ” f c t \n” ) ;
}

i n t main ( ) {
v o i d ( ∗ p f ) ( ) = &f c t ;
(∗ pf ) ( ) ;
}

140 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

#i n c l u d e < s t d i o . h>

int fct ( int a) {


return a ∗2;
}

i n t main ( ) {
i n t ( ∗ p f ) ( i n t ) = &f c t ;
p r i n t f ( ”%d\n” , ( ∗ p f ) ( 5 ) ) ;
}

141 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

1er programme

1 déclaration d’une structure thread


2 appel à pthread create

142 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>

void ∗ fonction () {
p r i n t f ( ” Thread \n” ) ;
}

i n t main ( ) {
pthread t thread ;
p t h r e a d c r e a t e (& t h r e a d , NULL , f o n c t i o n , NULL ) ;
return 0;
}

143 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

Terminaison
La terminaison du processus père entraà R ne la terminaison de ses
threads !

Remède
Attente de la terminaison des threads par le processus père (à
l’instar de wait pour les processus) :
int pthread join ( pthread t thread , void∗∗ thread return )

144 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>

void ∗ fonction () {
p r i n t f ( ” Thread \n” ) ;
}

i n t main ( ) {
pthread t thread ;
p t h r e a d c r e a t e (& t h r e a d , NULL , f o n c t i o n , NULL ) ;
p t h r e a d j o i n ( t h r e a d , NULL ) ;
return 0;
}

145 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

Partage de l’espace d’adressage

Les variables globales du processus père sont partagées par ses


threads.
Chaque thread possède ses propres variables locales (comme
les fonctions).

146 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>

i n t A = 5 ; // v a r i a b l e g l o b a l e
void ∗ fonction () {
i n t a = 7 ; // v a r i a b l e l o c a l e
p r i n t f ( ” l o c a l e : %d , g l o b a l e : %d\n” , a , A ) ;
}
i n t main ( ) {
pthread t thread ;
p t h r e a d c r e a t e (& t h r e a d , NULL , f o n c t i o n , NULL ) ;
p t h r e a d j o i n ( t h r e a d , NULL ) ;
p r i n t f ( ” g l o b a l e : %d\n” , A ) ;
return 0;
}

147 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

Accès concurrents aux données


Que se passe-t-il quand le processus et un thread accèdent à une
même donnée ?

148 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>

i n t a = 5 ; // v a r i a b l e g l o b a l e
void ∗ fonction () {
p r i n t f ( ” Thread \n” ) ;
a+=5;
}
i n t main ( ) {
pthread t thread ;
p t h r e a d c r e a t e (& t h r e a d , NULL , f o n c t i o n , NULL ) ;
p r i n t f ( ”%d\n” , a ) ; // Q u e l l e v a l e u r ?
p t h r e a d j o i n ( t h r e a d , NULL ) ;
p r i n t f ( ”%d\n” , a ) ; // e t i c i ?
return 0;
}

149 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

Indéterminisme
Différentes exécutions peuvent générer différents résultats !

150 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>

i n t a = 5 ; // v a r i a b l e g l o b a l e
void ∗ fonction () {
p r i n t f ( ” Thread \n” ) ;
a+=5;
}
i n t main ( ) {
pthread t thread ;
p t h r e a d c r e a t e (& t h r e a d , NULL , f o n c t i o n , NULL ) ;
a ∗=2;
p t h r e a d j o i n ( t h r e a d , NULL ) ;
p r i n t f ( ”%d\n” , a ) ; // e t i c i ?
return 0;
}

151 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

Création de multiples threads


Plusieurs threads peuvent exécuter :
la même fonction
des fonctions différentes

152 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>

void ∗ fonction () {
p r i n t f ( ” F o n c t i o n \n” ) ;
}
i n t main ( ) {
pthread t threads [ 2 ] ;
p t h r e a d c r e a t e (& t h r e a d s [ 0 ] , NULL , f o n c t i o n , NULL ) ;
p t h r e a d c r e a t e (& t h r e a d s [ 1 ] , NULL , f o n c t i o n , NULL ) ;
pthread join ( threads [0] , NULL ) ;
pthread join ( threads [1] , NULL ) ;
return 0;
}

153 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Création

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>
void ∗ fonction1 () {
p r i n t f ( ” F o n c t i o n 1 \n” ) ;
}
void ∗ fonction2 () {
p r i n t f ( ” F o n c t i o n 2 \n” ) ;
}
i n t main ( ) {
pthread t threads [ 2 ] ;
p t h r e a d c r e a t e (& t h r e a d s [ 0 ] , NULL , f o n c t i o n 1 , NULL ) ;
p t h r e a d c r e a t e (& t h r e a d s [ 1 ] , NULL , f o n c t i o n 2 , NULL ) ;
pthread join ( threads [0] , NULL ) ;
pthread join ( threads [1] , NULL ) ;
return 0;
}

154 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

155 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Communication

Communication entres les threads


Uniquement par :
des données globales (dans le segment data),
des données dynamiques allouées dans le tas.

Variables locales
Chaque thread possède sa propre pile et donc ses variables locales,
inaccessibles par les autres threads.

156 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Communication

Passage d’arguments aux threads fils


La fonction pthread create peut prendre en argument un
pointeur vers un argument à passer au thread créé.

Cast
Attention à bien utiliser des pointeurs ! La taille d’un pointeur est
dépendante de l’architecture.

157 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Communication

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>

void ∗ f o n c t i o n ( void ∗ arg ) {


p r i n t f ( ”%d\n” , ∗ ( u n s i g n e d i n t ∗ ) a r g ) ;
}

i n t main ( ) {
pthread t thread ;
unsigned i n t value = 5;
p t h r e a d c r e a t e (& t h r e a d , NULL , f o n c t i o n , ( v o i d ∗)& v a l u e ) ;
p t h r e a d j o i n ( t h r e a d , NULL ) ;
return 0;
}

158 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Communication

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>
s t r u c t Arg { i n t v a l u e ; c h a r ∗ s t r ; } ;
void ∗ f o n c t i o n ( void ∗ arg ) {
p r i n t f ( ”%d\n” , ( ( s t r u c t Arg ∗ ) a r g )−> v a l u e ) ;
p r i n t f ( ”%s \n” , ( ( s t r u c t Arg ∗ ) a r g )−> s t r ) ;
}
i n t main ( ) {
pthread t thread ;
s t r u c t Arg a r g ;
arg . value = 4;
arg . s t r = ” Hello ! ” ;
p t h r e a d c r e a t e (& t h r e a d , NULL , f o n c t i o n , ( v o i d ∗)& a r g ) ;
p t h r e a d j o i n ( t h r e a d , NULL ) ;
return 0;
}

159 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Communication

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>
void ∗ f o n c t i o n ( void ∗ arg ) {
p r i n t f ( ”%d\n” , ∗ ( u n s i g n e d i n t ∗ ) a r g ) ;
}
i n t main ( ) {
pthread t threads [ 1 0 ] ;
unsigned i n t id ;
f o r ( i d = 0 ; i d < 10 ; ++i d )
p t h r e a d c r e a t e (& t h r e a d s [ i d ] , NULL ,
f o n c t i o n , ( v o i d ∗)& i d ) ;
f o r ( i d = 0 ; i d < 10 ; ++i d )
p t h r e a d j o i n ( t h r e a d s [ i d ] , NULL ) ;
return 0;
}

160 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Communication

Accès concurrent au données partagées


Le thread parent peut modifier le contenu d’une variable passée à
un thread fils avant que le processus fils ne le récupère !

161 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Communication

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>
void ∗ f o n c t i o n ( void ∗ arg ) {
p r i n t f ( ”%d\n” , ∗ ( u n s i g n e d i n t ∗ ) a r g ) ;
}
i n t main ( ) {
pthread t threads [ 1 0 ] ;
unsigned i n t id ;
unsigned i n t i d s [ ] = {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9};
f o r ( i d = 0 ; i d < 10 ; ++i d )
p t h r e a d c r e a t e (& t h r e a d s [ i d ] , NULL ,
f o n c t i o n , ( v o i d ∗)& i d s [ i d ] ) ;
f o r ( i d = 0 ; i d < 4 ; ++i d )
p t h r e a d j o i n ( t h r e a d s [ i d ] , NULL ) ;
return 0;
}

162 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Table des matières


1 Contexte
Terminologie
Systèmes d’exploitation
Architectures
Enjeux

2 Du programme au processus
Programme exécutable
Chargement du programme en mémoire
Processus en mémoire

3 Gestion des processus par le système


Informations
Etats des processus
Signaux
Ordonnancement(Scheduling)

4 Processus
Création
Synchronisation
Communication

5 Mise en oeuvre des threads


Création
Communication
Synchronisation

163 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Entrelacements & Accès concurrents


Besoin de synchroniser les threads pour contrôler :
1 l’entrelacement des exécutions
2 les accès concurrents aux données partagées

164 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Cas d’utilisation

structures de données : plusieurs threads ajoutent/suppriment


des éléments dans une même liste.
accès concurrents à des périphériques.
base de données : plusieurs clients/threads accèdent à la
même base.
...

165 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Primitives de synchronisation

Mutex
Condition variables
Semaphores

166 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Mutex

Abbréviation de “Mutual Exclusion”.


Permet de garantir que l’exécution d’un thread ne sera pas
entrelacée avec d’autres threads partageant le “mutex”.
Mise en place d’une section critique.
Le mutex peut être vu comme un jeton que seule un thread
peut acquérir à la fois.

167 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Mutex : scénario

1 Déclaration du mutex
2 Initialisation du mutex
3 les threads tentent d’acquérir le mutex
4 1 seul peut l’obtenir, les autres sont mis en attente
5 le thread possédant le mutex continue sont exécution
6 le thread possédant le mutex libère le mutex
7 1 thread parmi ceux en attente est réveillé et récupère le
mutex
8 ...

168 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Mutex : mise en oeuvre

1 Déclaration d’une variable de type mutex : pthread mutex t


2 Initialisation : pthread mutex init(...)
3 Capture du mutex : pthread mutex lock(...)
4 Libération du mutex : pthread mutex unlock(...)
5 Destruction : pthread mutex destroy(...)

169 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>

p t h r e a d m u t e x t mutex ;

i n t main ( ) {
unsigned i n t i d s [ 4 ] = {0 , 1 , 2 , 3};
pthread t threads [ 4 ] ;
p t h r e a d m u t e x i n i t (&mutex , NULL ) ;

pthread c r e a t e (& t h r e a d s [0] , NULL , fct , ( v o i d ∗)& i d s [0]);


pthread c r e a t e (& t h r e a d s [1] , NULL , fct , ( v o i d ∗)& i d s [1]);
pthread c r e a t e (& t h r e a d s [2] , NULL , fct , ( v o i d ∗)& i d s [2]);
pthread c r e a t e (& t h r e a d s [3] , NULL , fct , ( v o i d ∗)& i d s [3]);
pthread e x i t (NULL ) ;
}

170 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

void ∗ f c t ( void ∗ arg ) {


unsigned i n t i d = ∗( unsigned i n t ∗) arg ;
unsigned i n t i ;
f o r ( i = 0 ; i < 10 ; ++i ) {
p t h r e a d m u t e x l o c k (&mutex ) ;
p r i n t f ( ” S t a r t i n g %d\n” , i d ) ;
sleep (1);
p r i n t f ( ” S t o p p i n g %d\n” , i d ) ;
p t h r e a d m u t e x u n l o c k (&mutex ) ;
}
}

171 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Condition variables

Mise en attente d’un thread tant qu’une condition n’est pas


remplie.
Réveil du thread en attente par un autre thread.
Utilisation combinée avec les mutex.

172 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Condition variables : scénario

1 Déclaration d’1 mutex + d’1 condition variable


2 Initialisation
3 Les threads tentent d’acquérir le mutex.
1 thread va se mettre en attente sur la variable et débloquer le
mutex.
1 autre thread signalera que la condition est vérifiée au thread
bloqué.
4 Destruction du mutex et de la condition variable.

173 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Condition variables : mise en oeuvre

1 Déclaration d’une condition variable : pthread cond t


2 Initialisation : pthread cond init(...)
3 Mise en attente : phread cond wait(...)
4 Envoi du signal : phread cond signal(...)
5 Destruction : phread cond destroy(...)

174 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

#i n c l u d e <p t h r e a d . h>
#i n c l u d e < s t d i o . h>
p t h r e a d m u t e x t mutex ;
p t h r e a d c o n d t cond ;
unsigned i n t count = 0;
i n t main ( ) {
pthread t threads [ 4 ] ;
p t h r e a d m u t e x i n i t (&mutex , NULL ) ;
p t h r e a d c o n d i n i t (&cond , NULL ) ;
p t h r e a d c r e a t e (& t h r e a d s [ 0 ] , NULL , compute , NULL ) ;
p t h r e a d c r e a t e (& t h r e a d s [ 1 ] , NULL , o b s e r v e r , NULL ) ;
p t h r e a d j o i n ( t h r e a d s [ 0 ] , NULL ) ;
p t h r e a d j o i n ( t h r e a d s [ 1 ] , NULL ) ;
p t h r e a d m u t e x d e s t r o y (&mutex ) ;
p t h r e a d c o n d d e s t r o y (& cond ) ;
}

175 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

void ∗ observer () {

p t h r e a d m u t e x l o c k (&mutex ) ;

p r i n t f ( ” O b s e r v e r h a s mutex ! \ n” ) ;

i f ( count < 10)


p t h r e a d c o n d w a i t (&cond , &mutex ) ;

p r i n t f ( ” 10 ! \ n” ) ;

p t h r e a d m u t e x u n l o c k (&mutex ) ;

176 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

v o i d ∗ compute ( v o i d ∗ a r g ) {
unsigned i n t i ;
f o r ( i = 0 ; i < 20 ; ++i ) {
p t h r e a d m u t e x l o c k (&mutex ) ;
p r i n t f ( ” Compute : i n c %d\n” , i ) ;

i f ( c o u n t == 1 0 ) {
p r i n t f ( ” c o u n t = 10\ n” ) ;
p t h r e a d c o n d s i g n a l (& cond ) ;
}
++c o u n t ;
p t h r e a d m u t e x u n l o c k (&mutex ) ;
sleep (1);
}
}

177 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Semaphores

Mutex avec compteur.


Le compteur est décrémenté chaque fois qu’un thread
récupère le sémaphore.
Lorsque le compteur est à zéro, les threads sont mis en
attente.

178 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Semaphores : scénario

1 Déclaration d’un sémaphore.


2 Initialisation du sémaphore (compteur).
3 Les threads récupèrent le sémaphore tant que le compteur >
0.
4 Si le compteur == 0 les threads sont mis en attente.
5 Chaque fois qu’un thread libère le sémaphore, le compteur est
incrémenté et un thread en attente est réveillé.

179 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

Semaphores : mise en oeuvre

1 #include <semaphore.h>

2 Déclaration d’un sémaphore : sem t


3 Initialisation : sem init(...)
4 Capture : sem wait(...)
5 Libération : sem post(...)
6 Destruction : sem destroy(...)

180 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

#i n c l u d e < s t d i o . h>
#i n c l u d e <p t h r e a d . h>
#i n c l u d e <s e m a p h o r e . h>
s e m t sem ;
i n t main ( ) {
pthread t threads [ 4 ] ;
s e m i n i t (&sem , 0 , 2 ) ;
unsigned i n t i ;
unsigned i n t i d s [ ] = {0 , 1 , 2 , 3};
f o r ( i = 0 ; i < 4 ; ++i )
p t h r e a d c r e a t e (& t h r e a d s [ i ] , NULL ,
f c t , ( v o i d ∗)& i d s [ i ] ) ;
f o r ( i = 0 ; i < 4 ; ++i )
p t h r e a d j o i n ( t h r e a d s [ i ] , NULL ) ;
s e m d e s t r o y (&sem ) ;
}

181 / 182
Contexte
Introduction
Du programme au processus
Création
Gestion des processus par l’OS
Communication
Processus
Synchronisation
Threads

Synchronisation

void ∗ f c t ( void ∗ arg ) {

s e m w a i t (&sem ) ;

p r i n t f ( ” Thread %d\n” , ∗ ( u n s i g n e d i n t ∗ ) a r g ) ;
sleep (4);

s e m p o s t (&sem ) ;

182 / 182

Vous aimerez peut-être aussi