Sommaire
ATTENTION :
Ce qu'il faut faire :
Pour compiler :
gcc -o Exo0 -Wall Exo0.c -lpthread
On s'efforcera de retirer tous les warnings.
Le résultat de la commande Exo0 est un affichage du type :
main (Tid (0x)1 vient de creer : (0x)2 main (Tid (0x)1 vient de creer : (0x)3 main (Tid (0x)1 vient de creer : (0x)4 main (Tid (0x)1 vient de creer : (0x)5 ------main Fin de main (0x)1
Copier le fichier Exo0.c dans un nouveau fichier appelé Exo1.c, modifier ce dernier en utilisant pthread_join et vérifier que les printf sont bien exécutés.
Pour information :
Exemple de création de threads avec passage
de paramétres : ici.
On veut écrire un programme dans lequel main, comme dans l'exercice précédent, attend la fin de tous les threads qu'il a créé. Mais on ajoute une contrainte :
pthread_join ne convient pas puisqu'elle impose un ordre sur
la fin des threads dont on attend la terminaison.
On utilisera donc une variable conditionnelle
sur laquelle se bloque main une fois qu'il a créé et lancé
tous les threads.
Cette variable conditionnelle sera utilisée par
les threads fils pour indiquer leur terminaison.
On donne un canevas de ce programme dans le fichier
VarCond.c .
On vous demande :
On donne des corrigés : ici et ici .
SCENARIO :
Ici, il y a une seule donnée partagée qui s'apelle Donnee, utilisée par des threads
lecteurs et des threads écrivains.
Les threads écrivains incrémentent la variable partagée de différentes valeurs.
Quand cette variable atteint une valeur maximum, donnée par VALMAX, alors tous les threads s'arrêtent, aussi bien les lecteurs que les écrivains.
L'application doit fonctionner de la façon suivante :
|
Pour éviter ce dysfonctionnement, qui peut se traduire par la famine pour les écrivains, l'arrivée d'un écrivain doit bloquer tous les lecteurs suivants. Voici le comportement qui sera adopté : lorqu'un écrivain se présente, il attend la sortie des lecteurs courants, les lecteurs qui le suivent sont bloqués. Lorsque tous ces lecteurs sont sortis, l'écrivain modifie la donnée, et on sert le (ou les) écrivain(s) qui seraient arrivés entre-temps.
On utilise les outils de synchronisation suivants :
votre-login$ ./lec-ecr 3 0 Entree_SC_Lect : Lecteur 283648 w_w =0, nblect = 0 Entree_SC_Lect : Lecteur 284256 w_w =0, nblect = 1 Entree_SC_Lect : Lecteur 284864 w_w =0, nblect = 2 Lecteur 283648 : donnee = 20 Lecteur 283648: Fin. Lecteur 284256 : donnee = 20 Lecteur 284864 : donnee = 20 Lecteur 284256: Fin. Lecteur 284864: Fin.
votre-login$ ./lec-ecr 0 3 ----------------------Entree_SC_Ecr : Ecrivain 283648 w_w =0, nblect = 0 ----------------------Entree_SC_Ecr : Ecrivain 284256 w_w =0, nblect = -1 ----------------------Entree_SC_Ecr : Ecrivain 284864 w_w =1, nblect = -1 ----------------------Sortie_SC_Ecr : Ecrivain 283648 w_w =2, nblect = -1 ----------------------Ecrivain 283648: ecrit 2 ----------------------Sortie_SC_Ecr : Ecrivain 284256 w_w =1, nblect = -1 ----------------------Ecrivain 284256: ecrit 4 ... ----------------------Ecrivain 283648: ecrit 15 ----------------------Entree_SC_Ecr : Ecrivain 284864 w_w =0, nblect = 0 ----------------------Entree_SC_Ecr : Ecrivain 283648 w_w =0, nblect = -1 ----------------------Sortie_SC_Ecr : Ecrivain 284864 w_w =1, nblect = -1 ----------------------Ecrivain 284864: ecrit 18 ----------------------Entree_SC_Ecr : Ecrivain 284256 w_w =0, nblect = -1 ----------------------Sortie_SC_Ecr : Ecrivain 283648 w_w =1, nblect = -1 ----------------------Ecrivain 283648: ecrit 19 ----------------------Sortie_SC_Ecr : Ecrivain 284256 w_w =0, nblect = -1 ----------------------Ecrivain 284256: ecrit 21 Ecrivain 283648: Fini. Ecrivain 284256: Fini. Ecrivain 284864: Fini.
votre-login$ ./lec-ecr 3 2 ----------------------Entree_SC_Ecr : Ecrivain 283648 w_w =0, nblect = 0 ----------------------Entree_SC_Ecr : Ecrivain 284256 w_w =0, nblect = -1 Entree_SC_Lect : Lecteur 284864 w_w =1, nblect = -1 Entree_SC_Lect : Lecteur 284864 va se bloquer. Entree_SC_Lect : Lecteur 285472 w_w =1, nblect = -1 Entree_SC_Lect : Lecteur 285472 va se bloquer. Entree_SC_Lect : Lecteur 286080 w_w =1, nblect = -1 Entree_SC_Lect : Lecteur 286080 va se bloquer. ----------------------Sortie_SC_Ecr : Ecrivain 283648 w_w =1, nblect = -1 ----------------------Ecrivain 283648: ecrit 2 ----------------------Sortie_SC_Ecr : Ecrivain 284256 w_w =0, nblect = -1 ----------------------Ecrivain 284256: ecrit 4 Entree_SC_Lect : Lecteur 284864 debloque. Entree_SC_Lect : Lecteur 285472 debloque. Entree_SC_Lect : Lecteur 286080 debloque. ... Entree_SC_Lect : Lecteur 286080 w_w =0, nblect = -1 Entree_SC_Lect : Lecteur 286080 va se bloquer. Entree_SC_Lect : Lecteur 285472 w_w =0, nblect = -1 Entree_SC_Lect : Lecteur 285472 va se bloquer. ----------------------Sortie_SC_Ecr : Ecrivain 284256 w_w =0, nblect = -1 ----------------------Ecrivain 284256: ecrit 20 Entree_SC_Lect : Lecteur 284864 debloque. Entree_SC_Lect : Lecteur 286080 debloque. Entree_SC_Lect : Lecteur 285472 debloque. Lecteur 284864 : donnee = 20 Lecteur 284864: Fin. Lecteur 285472 : donnee = 20 Lecteur 286080 : donnee = 20 Lecteur 285472: Fin. Ecrivain 283648: Fini. Lecteur 286080: Fin. Ecrivain 284256: Fini.