Chapitre 2Processus & Threads
© Rim Moussa
2005-2006
2
Plan du chapitre
1. Processus
2. Threads
3. Ordonnancement
4. Communication interprocessus
3
Processus Un processus est une activité: programme, entrées, sorties,
état Systèmes monoprocesseurs: pseudo-parallélisme Multiprogrammation: basculement entre processus Créer un processus? à l’initialisation du système, par un
processus, requête utilisateur, job de trait par lots.– UNIX: fork –création d’un clone et execve –modifier l’image du processus– Windows: CreateProcess
Processus– Démons (daemon) ou en arrière-plan, exples: courriers électroniques,
pages web…– Premier-plan
Les voir?– Ctrl+alt+del sur Windows– ps sur UNIX
4
… Processus Fin de Processus
– Volontaire: arrêt normal ou arrêt pour erreur (le fichier à compiler n’existe pas)
– Involontaire: arrêt pour erreur fatale (division par 0) ou arrêté par un autre processus (Unix: kill, Windows: TerminateProcess)
Hiérarchie de Processus– Existe sous UNIX, arborescence de parent-enfants– N’existe pas sous Windows, CreateProcess retourne un HANDLE
utilisé pour contrôler le processus
Implémentation de Processus– Processus possède son propre espace d’adressage: programme,
données, pile.– Le changement de contexte (changement de processus) Table
de processus, avec une entrée/ processus contenant registres, identificateur, ptr vers le segment texte, ptr vers segment de données, ptr vers le segment de pile, état …
5
… Etats de Processus
En cours d’exécution
Bloqué Prêt
– Le processus est bloqué, en attente d’une donnée, événement
– L’ordonnanceur choisit un autre processus– L’ordonnanceur choisit ce processus– La donnée devient disponible
(1)(3)
(2)
(4)
6
Threads Un processus possède un espace d’adressage et un thread de
contrôle unique. Un thread –processus léger ou leightweight process inclut:
– un compteur ordinal, qui effectue le suivi des instructions à exécuter
– des registres, qui détiennent les variables en cours.
– une pile, qui contient l’historique de l’exécution.
Pour plus de performances, cas de threads liés aux E/Ss, d’autres de traitement Multithreading: +sieurs threads dans le même espace d’adressage.
Etats d’un thread: en cours d’exécution, bloqué, prêt ou arrêté. Procédures de bibliothèque: thread_create, thread_exit,
thread_wait, thread_yield (abandon volontaire de la CPU). Temps de création d’un processus >> Temps de création d’un
thread (100 )
7
… Trait de Texte multithreaded
Disquenoyau
Thread 1: remet en forme le document
Thread 2: interaction avec l’utilisateur
Thread 3: écrit périodiquement le contenu de la RAM sur le disque
AbsbjshdDnddjkjdqHqdjlqdjlJddmkm
Djdlqjdjdqdjdqkmkd
AbsbjshdDnddjkjdqHqdjlqdjlJddmkm
Djdlqjdjdqdjdqkmkd
AbsbjshdDnddjkjdqHqdjlqdjlJddmkm
Djdlqjdjdqdjdqkmkd
clavier
8
… Serveur Web multithreaded
noyau
Pool de worker threads
Dispatcher Thread
Cache de pages web
Les pages web les + consultées sont dans le cache.
Le dispatcher lit les requêtes entrantes
Le worker vérifie le cache, sinon effectue un read sur le disque, donc devient bloqué sur une E/S
Worker
while (TRUE) { get_next_request(&buf); handoff_work(&buf);}
while (TRUE) { wait_for_work(&buf); look_for_page_in_cache(&buf, &page); if (page_not_in_cache(&page)) read_page_from_disk(&buf, &page); return_page(&page);}
Dispatcher
9
… Implémentation de ThreadsSoit dans l’Espace Utilisateur ou dans le Noyau
noyau
Espace user
Processus
Thread
Système d’exécution
Table des threads
Table des processus
Système d’exécution (runtime system): gére la table de threads,
le basculement entre threads en cas d’implem en espace user est + rapide que celui en mode noyau.
Implem en espace user: le processus a son propre algo d’ordonnancement entre les threads
10
OrdonnancementOrdonnanceur (scheduler): partie du SE qui sélectionne les processus.
Algo d’ordonnancement (scheduling algorithm)
- ~ non-préemptif: sélectionne un processus, puis le laisse s’exécuter jusqu’à ce qu’il se bloque (E/S, wait) ou se termine.
- ~ préemptif: sélectionne un processus et le laisse s’exécuter pendant un quantum, préemption par l’interruption horloge
Comportement de Processus: - Processus de traitement- Processus d’E/S
11
…Objectifs de l’ordonnancementTous les systèmesÉquité: attribuer à chaque processus un temps CPU équitable
Équilibre: toutes les parties du système sont occupées
Systèmes de traitement par lotsCapacité de Trait: optimiser le #jobs/ heure
Délai de rotation: réduire le délai entre la soumission et l’achèvement
Taux d’utilisation du processeur
Systèmes interactifsTemps de réponse: réponse rapide aux requêtes
Systèmes temps réelRespect des délais: éviter de perdre les données
Prévisibilité: éviter la dégradation de la qualité
12
… Algo d’ordonnancement 1er arrivé, 1er servi (first come first served)
Le job le plus court en premier (shortest job first)
Délais d’exécution connus
Shortest remaining time next
Tourniquet (round robin)
Quantum court: trop de changement de contexte
Quantum long: dégradation temps de réponse aux requêtes interactives
Par Priorités
Prévenir contre les situations de « famine » en diminuant la priorité du processus à chaque interruption ou priorité égale à l’inverse de la fraction d’utilisation du dernier quantum...
Par Tirage au Sort
13
… Ordonnancement à 3 niveaux
Processeur
Mémoire Principale
DisqueOrdonnanceur du
processeur
Ordonnanceu
r
de mém
oire
Job entrant
File d’attente
Ordonnanceur
d’admission
1. O. d’admission: Mélange jobs E/S et CPU, shortest job first…
2. O. de mémoire: processus en mémoire ou sur disque ? Niveau de multiprogrammation?
3. O. du processeur: Sélection des processus prêts en mémoire celui qui va s’exécuter
14
Communication interprocessus
1. Conditions de Concurrence
2. Sections Critiques
3. Exclusion Mutuelle
4. Sommeil & Activation
5. Sémaphores
6. Mutex
7. Moniteurs
8. Echange de Messages
9. Barrières
15
Conditions de Concurrence Conditions de concurrence (race conditions): situation où 2
processus ou plus effectuent des lectures et des écritures conflictuelles.
Exemple du Spouleur d’impression– Un processus qui veut imprimer un fichier, entre son nom dans un
répertoire de spoule– Le processus démon d’impression regarde périodiquement s’il y a
des fichiers à imprimer. Il a 2 variables:• in: pointe vers la prochaine entrée libre.• out: pointe vers le prochain fichier à imprimer
– in = 7, out = 4– A et B deux processus qui veulent imprimer un fichier – A >> lire in, next_free_slot = 7– Interruption: la CPU bascule vers le processus B– B >> lire in, next_free_slot = 7, entrée7 = fichierB, in = 8 – A >> entrée7 = fichierA, in = 8– Problème: le fichierB ne sera pas imprimé
16
… Conditions de Concurrence
Comment éviter les conditions de concurrence?
Solution: Interdire que plusieurs processus lisent et
écrivent des données partagées simultanément.
Exclusion Mutuelle: permet d’assurer que si un
processus utilise une variable ou fichier partagés, les
autres processus seront exclus de la même activité
17
Les Sections Critiques
A
B
t1 t2 t3 t4
A entre dans sa section critique
B tente d’entrer dans sa section critique
A quitte sa section critique
B entre dans sa section critique
B quitte sa section critique
les Sections Critiques, méthode d’exclusion mutuelle
18
L’Exclusion Mutuelle avec Attente Active (busy waiting) Désactivation des interruptions
– Après son entrée dans une SC, un processus désactive les interruptions, puis les réactive
– Il empêche ainsi l’horloge d’envoyer des interruptions et le processeur de basculer
– Il est imprudent de permettre à des processus user de désactiver les interruptions
Variables de verrou (lock)– Avant d’entrer en SC, tester la valeur de verrou, si verrou = 0,
verrou 1, entrer en SC– Défaillance: 2 processus peuvent entrer simultanément dans leurs
sections critiques comme le spouler d’impression
Alternance Stricte– la variable turn porte le numéro du processus dont c’est le tour
d’entrer en SC. Chaque processus inspecte la valeur de la variable, avant d’entrer en SC.
– Inconvénient: consomme bcp de temps CPU
19
… Exclusion Mutuelle avec Attente Active (busy waiting) … Alternance Stricte
while (TRUE) { while (TRUE) { while (turn != 0); while (turn != 1); critical_region(); critical_region(); turn = 1; turn = 0; non_critical_region(); non_critical_region();
} }
– Les attentes actives sont performantes dans le cas où elles sont brèves. En effet, il y’ a risque d’attente
• P0 quitte la CS, turn = 1
• P1 termine sa CS, turn = 0
• Les 2 processus sont en section non critique
• P0 exécute sa boucle, quitte la SC et turn = 1
• Les 2 processus sont en section non critique
• P0 quoiqu’il a terminé, il ne peut pas entrer en SC, il est bloqué
20
… Exclusion Mutuelle avec Attente Active (busy waiting) Solution de Peterson: combinaison de variables verrou, de variables
d’avertissement sans alternance stricte. #define FALSE 0 #define TRUE 1 #define N 2 // nombre de processus int turn; // à qui le tour? int interested[N]; // initialement les valeurs sont false void enter_region (int process) { int other; other = 1 – process; interested[process] = TRUE; turn = process; while (turn == process && interested[other] == TRUE); } void leave_region (int process) { interested[process] = FALSE; }
21
… Exclusion Mutuelle avec Attente Active (busy waiting) Instruction TSL
– solution qui nécessite de l’aide du matériel.
– TSL acronyme de Test and Set Lock
– Elle consiste en la lecture du contenu du mot mémoire Lock du registre
RX, puis stocker d’une valeur différente de 0 à l’adresse mémoire lock.
Ces opérations sont indivisibles: le processeur exécutant TSL
verrouille le bus mémoire.
enter_region:
TSL REGISTER, LOCK | copie lock dans le registre et la définit à 1
CMP REGISTER, #0 | tester si lock est égale à 0
JNE enter_region | si elle est différente de 0 boucle
RET | retour à l’appelant, entre en SC
leave_region:
MOVE LOCK, #0 | stocke un 0 dans lock
RET | retour à l’appelant
22
Problème du consommateur-producteur Connu aussi sous le nom de tampon délimité (bounded buffer). 2 processus partagent un tampon commun de taille fixe N. Le producteur place des jetons dans le tampon. Le consommateur récupère un jeton Problème 1: le producteur souhaite placer un nouveau jeton
alors que le tampon est plein. Problème 2: le consommateur souhaite récupérer un jeton alors
que le tampon est vide Count dénote le nombre de jetons dans le tampon
23
Sommeil & Activation Ne consomme pas de la
CPU comme l’attente active
Primitives de
communication: – sleep: appel système qui
provoque le blocage de
l’appelant
– wake up: appel système
qui réveille un processus.
Problème du
producteur-
consommateur
void producer (void) { int item; while (TRUE) { item = produce_item(); if (count == N) sleep(); insert_item(item); count++; if (count == 1) wakeup(consumer); } }void consumer (void) { int item; while (TRUE) { if (count == 0) sleep(); item = remove_item(); count--; if (count == N-1) wakeup(producer); consume_item(item); } }
#define N 100int count = 0;
24
… Sommeil & Activation Problème de blocage:
– Le consommateur note que le tampon est vide
– Interruption: arrêt du consommateur sans qu’il parte en sommeil
– Le producteur insère un jeton, incrémente le décompte, appelle wakeup pour réveiller le consommateur
– Le signal wakeup est perdu, car le consommateur n’est pas en sommeil
– Le consommateur reprend, pour lui le tampon est vide, il dort
– Le producteur remplit le tampon et dort
Solution: ajouter un bit d’attente d’éveil. – Quand un wakeup est envoyé à un processus le bit est à 1;
– le consommateur teste le bit, s’il est à 1, il le remet à 0 et reste en éveil
– Cette solution est + difficile à généraliser en cas de + sieurs processus.
25
Sémaphores Sémaphore: # de wakeup enegistrés 2 opérations:
– down: si la valeur de la variable sémaphore est > 0, la décrémenter; si la valeur est nulle: sleep
– up: incrémenter la valeur de la sémaphore et réveiller au hasard un processus dormant
– down et up sont implémentées en tant que appels système,
– le SE désactive les interruptions, et c’est ainsi que les opérations de vérification, de màj et de sommeil s’exécutent de manière atomique
Problème du producteur-consommateur– 3 sémaphores: full, empty et mutex
– full: # d’emplacemens occupés dans le tampon
– empty: # d’emplacements vides dans le tampon
– mutex: pour s’assurer que le consommateur et le producteur n’accèdent pas simultanément au tampon
26
… Sémaphores
#define N 100Typedef int semaphore;semaphore mutex = 1;semaphore empty = N;semaphore full = 0;
void producer (void) { int item; message m; while (TRUE) { item = produce_item(); down(&empty); down(&mutex); insert_item(item); up(&mutex); up(&full); } }
void consumer (void) { int item; while (TRUE) { down(&full); down(&mutex); item = remove_item(&m); up(&mutex); up(&empty); consume_item(item); } }
27
Mutex Sémaphore d’exclusion mutuelle, où la fonction décompte n’est pas
nécessaire. Une mutex a 2 états: déverrouillé: valeur 0 ou verrouillé Si +sieurs threads sont bloqués sur une mutex, l’un d’entre eux est
choisi au hasard pour prendre possession du verrou. mutex_lock et mutex_unlock
mutex_lock:
TSL REGISTER, MUTEX | copie mutex dans le registre et la définit à 1
CMP REGISTER, #0 | tester si mutex est égale à 0
JSE ok | si elle est différente de 0 retour
CALL thread_yield | relâcher la CPU
ok:
RET | retour à l’appelant
mutex_unlock:
MOVE MUTEX, #0 | stocke un 0 dans mutex
RET | retour à l’appelant
! Comparer au code d’enter_region slide 17
28
Moniteurs Collection de procédures, de variables, de structures
de données regroupées dans un module. Un processus ne peut appeler que les procédures du
moniteur. Les moniteurs sont des constructions de langage, et
c’est au compilateur d’implanter l’exclusion mutuelle sur les entrées du moniteur.
Problème du producteur-consommateur– 2 variables conditionnelles (vc): full et empty
– Quand une procédure du moniteur découvre qu’elle ne peut plus poursuivre, elle effectue un wait sur une vc
– Si un signal est adressé une vc attendue, un processus est réactivé.
29
… Moniteursmonitor ProducteurConsommateur
condition full, empty;
integer count;
procedure insert (item: integer)
begin
if count = N then wait(full)
insert_item(item);
count++;
if (count = 1) then signal(empty);
end;
function remove: integer
begin
if count = 0 then wait(empty);
remove = remove_item;
count--;
if (count = N –1) then signal(full);
end;
count = 0;
end monitor;
procedure producteur
begin
while true do {
item = produce_item;
ProducteurConsommateur.insert(item);
}
end;
procedure consommateur
begin
while true do {
item = ProducteurConsommateur.remove;
consume_item(item);
}
end;
30
Echange de Messages Convient aux systèmes distribués 2 primitives appels systèmes: send et receive
– send (destination, &message)– receive (source, &message)
Problèmes– Perte de messages dans le réseau, – + de fiabilité par les ACKs, la retransmission de messages
et la détection de doublons
Problème du producteur-consommateur– Les messages émis et non encore reçus sont mis en
mémoire par le SE– Le consommateur envoie N messages vides au producteur– Le producteur remplit chaque message vide reçu
31
…Echange de Messages
#define N 100void producer (void) { int item; message m; while (TRUE) { item = produce_item(); receive(consumer, &m); build_message(&m, item); send(consumer, &m); } }void consumer (void) { int item, i; for(i=0; i<N;i++) send(producer, &m); while (TRUE) { receive(producer,&m); item = extract_item(&m); send(producer, &m); consume_item(item); } }
Problème, si le producer
travaille + vite que le
consumer
le producer envoie tous
les messages pleins et reste
bloqué en attente d’un
message vide.
32
Les Barrières Mécanisme de synchronisation destiné aux groupes de processus.
Cas d’applications décomposées en phases, où aucun processus ne
peut entrer dans la phase suivante tant que tous les processus ne sont
pas prêts à y entrer.
Solution: placer une barrière, et quand un processus atteint la barrière il
est bloqué jusqu’à ce que tous les processus atteignent la barrière.
Bar
rière
Bar
rière
A
B
C
A
B
CB
arriè
re
A
B
C