La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Chap. 71 Synchronisation de Processus (ou threads, ou fils ou tâches) Chapitre 7

Présentations similaires


Présentation au sujet: "Chap. 71 Synchronisation de Processus (ou threads, ou fils ou tâches) Chapitre 7"— Transcription de la présentation:

1 Chap. 71 Synchronisation de Processus (ou threads, ou fils ou tâches) Chapitre 7

2 Chap. 72 Problèmes avec concurrence = parallélisme n Les threads concurrents doivent parfois partager données (fichiers ou mémoire commune) et ressources u On parle donc de threads coopérants n Si laccès nest pas contrôlé, le résultat de lexécution du programme pourra dépendre de lordre dentrelacement de lexécution des instructions (non-déterminisme). n Un programme pourra donner des résultats différents et parfois indésirables de fois en fois

3 Chap. 73 Exemple 1 n Deux threads exécutent cette même procédure et partagent la même base de données n Ils peuvent être interrompus nimporte où n Le résultat de l exécution concurrente de P1 et P2 dépend de l`ordre de leur entrelacement M. X demande une réservation davion Base de données dit que fauteuil A est disponible Fauteuil A est assigné à X et marqué occupé

4 Chap. 74 Vue globale dune exécution possible M. Guy demande une réservation davion Base de données dit que fauteuil 30A est disponible Fauteuil 30A est assigné à Guy et marqué occupé M. Leblanc demande une réservation davion Base de données dit que fauteuil 30A est disponible Fauteuil 30A est assigné à Leblanc et marqué occupé Interruption ou retard P1 P2

5 n Exécuter deux fois en parallèle le code suivant: n Quel pourrait être le résultat dans b? Exemple 2 Chap. 75 b=a b++ a=b

6 Hypothèse de partage de données Chap. 76 Partagées entre threads Les données partagées ne sont pas souvegardées quand on change de thread

7 Chap. 77 b=a b++ a=b b=a b++ a=b P1 P2P2 Supposons que a soit 0 au début P1 travaille sur le vieux a donc le résultat final sera a=1. Sera a=2 si les deux tâches sont exécutées lune après lautre Cas pratique: a est un compteur daccès dans une page web interruption Deux opérations en parallèle var a partagée entre thread var b est privée à chaque thread

8 Chap. 78 3ème exemple Thread P1 static char a; void echo() { cin >> a; cout << a; } Thread P2 static char a; void echo() { cin >> a; cout << a; } Si la var a est partagée, le premier a est effacé Si elle est privée, lordre daffichage est renversé

9 Asynchronie des threads n Quand plusieurs threads exécutent en parallèle, nous ne pouvons pas faire dhypothèses sur la vitesse dexécution des threads, ni leur entrelacement n Peuvent être différents à chaque exécution du programme Chap. 79

10 10 Autres exemples n Des threads qui travaillent en simultanéité sur une matrice, par ex. un pour la mettre à jour, l`autre pour en extraire des statistiques n Problème qui affecte le programme du tampon borné, v. manuel

11 Chap. 711 Section Critique n Partie dun programme dont lexécution ne doit pas entrelacer avec autres programmes u Indivisibilité ou atomicité de la section critique n Une fois quun processus ou fil y entre, il faut lui permettre de terminer cette section sans permettre à autres de jouer sur les mêmes données u La section critique doit être verrouillée afin de devenir atomique

12 Entrelacement de threads A et B Chap. 712 A A Contin. A Contin. B B contin Les flèches indiquent délais ou interruptions Beaucoup de possibilités, selon les points où A et B sont interrompus

13 Atomicité de threads A et B par effet du verrou Chap. 713 A B A B OU Seulement deux possibilités, quand chacun est exécuté sans interruptions

14 Section critique Chap. 714 M. X demande une réservation davion Base de données dit que fauteuil A est disponible Fauteuil A est assigné à X et marqué occupé atomique

15 Chap. 715 Le problème de la section critique n Lorsquun thread manipule une donnée (ou ressource) partagée avec autres, nous disons quil se trouve dans une section critique (associée à cette donnée) n Le problème de la section critique est de trouver un algorithme d`exclusion mutuelle de threads dans l`exécution de leur CritSect afin que le résultat de leurs actions ne dépendent pas de lordre dentrelacement de leur exécution (avec un ou plusieurs processeurs) n Lexécution des sections critiques doit être mutuellement exclusive et atomique: à tout instant, un seul thread peut exécuter une CritSect pour une donnée (même lorsquil y a plusieurs UCT) n Ceci peut être obtenu en plaçant des instructions spéciales dans les sections d`entrée et sortie u Implantation du cadenas

16 Chap. 716 Deux simplifications n Pour simplifier, parfois nous ferons lhypothèse quil ny a quune seule CritSect dans un thread n Et nous ne ferons plus distinction entre CritSect pour différentes données

17 Chap. 717 Structure dun programme type n Le programme est présenté comme boucle infinie: while(true) n Chaque thread doit donc demander une permission avant dentrer dans une CritSect n La section de code qui effectue cette requête est la section dentrée n La section critique est normalement suivie dune section de sortie (leave CritSect) n Le code qui reste est la section non-critique while (true) { enterCritSect CritSect leaveCritSect nonCritSect } atomique

18 Chap. 718 Application M. X demande une réservation davion enterCritSect Base de données dit que fauteuil A est disponible Fauteuil A est assigné à X et marqué occupé leaveCritSect Section critique

19 Chap. 719 Critères nécessaires pour solutions valides (*) n Exclusion Mutuelle u En tout moment, au plus un thread peut être dans une CritSect n Déroulement u Une CritSect ne sera donnée quà un thread qui attend dy entrer u Chaque fois quune CritSect devient disponible, sil y a des threads qui lattendent, un deux doit être capable dy entrer ( pas dinterblocage ) n Attente bornée (pas de famine) u Un thread qui attend dentrer dans une CritSect pourra enfin y entrer F = aucun thread ne peut être exclu à jamais de la CritSect à cause dautres threads qui la monopolisent n Notez la différence entre interblocage et famine (*) Définitions plus compliquée dans le manuel, mais selon moi sans besoin

20 Chap. 720 Types de solutions n Solutions par logiciel u des algorithmes qui nutilisent pas d`instruction spéciales n Solutions fournies par le matériel u sappuient sur lexistence de certaines instructions (du processeur) spéciales n Solutions fournies pas le SE u procure certains appels du système au programmeur n Toutes les solutions se basent sur latomicité de laccès à la mémoire centrale: une adresse de mémoire ne peut être affectée que par une instruction à la fois, donc par un thread à la fois. n Plus en général, toutes les solutions se basent sur lexistence dinstructions atomiques, qui fonctionnent comme Sections Critiques de base

21 Chap. 721 Solutions par logiciel (pas pratiques, mais intéressantes pour comprendre le pb) n Nous considérons dabord 2 threads u Algorithmes 1 et 2 ne sont pas valides F Montrent la difficulté du problème u Algorithme 3 est valide (algorithme de Peterson) n Notation u Débutons avec 2 threads: T0 et T1 u Lorsque nous discutons de la tâche Ti, Tj sera toujours lautre tâche (i != j) u while(X){A}: repète A tant que X est vrai F while(X): attend tant que X est vrai

22 Chap. 722 Idée de lalgorithme 1 n Les threads se donnent mutuellement le tour u T0 T1 T0 T1… n Réalise lexclusion mutuelle, mais viole le principe du déroulement: u Une CritSect pourra être donnée à des threads qui nen ont pas besoin u P.ex. après T0, T1 pourrait navoir pas besoin dentrer

23 Chap. 723 Algorithme 1: threads se donnent mutuellement le tour n La variable partagée tour est initialisée à 0 ou 1 n La CritSect de Ti est exécutée ssi tour = i n Ti est actif à attendre si Tj est dans CritSect. n Fonctionne pour lexclusion mutuelle! n Mais critère du déroulement pas satisfait car lexécution des CritSect doit strictement alterner Thread Ti: while(true){ while(tour!=i); CritSect tour = j; nonCritSect } T0 T1 T0 T1… même si lun des deux nest pas intéressé du tout Rien faire

24 Chap. 724 Thread T0: While(true){ while(tour!=0); CritSect tour = 1; nonCritSect } Thread T1: While(true){ while(tour!=1); CritSect tour = 0; nonCritSect } Algorithme 1 vue globale Initialisation de tour à 0 ou 1 Rien faire

25 Chap. 725 Exemple: supposez que tour=0 au début Thread T0: while(tour!=0); // premier à entrer CritSect tour = 1; nonCritSect while(tour!=0); // entre quand T1 finit CritSect tour = 1; nonCritSect etc... Thread T1: while(tour!=1); // entre quand T0 finit CritSect tour = 0; nonCritSect while(tour!=1); // entre quand T0 finit CritSect tour = 0; nonCritSect etc...

26 Chap. 726 Généralisation à n threads n Chaque fois, avant quun thread puisse rentrer dans la section critique, il lui faut attendre que tous les autres aient eu cette chance! u En claire contradiction avec lexigence de déroulement F Supposez le cas de threads, dont seulement quelques uns sont actifs

27 Algorithme 2 n Lalgorithme 2 prend en compte la critique à lalgorithme 1: u Donne la CritSect seulement aux threads qui la veulent n Cependant on ne peut pas permettre à un processus de se redonner systématiquement la CritSec famine u Faut que chaque processus qui veut entrer donne une chance à des autres avant dy entrer Chap. 727

28 Chap. 728 Algorithme 2 ou lexcès de courtoisie... n Une variable Booléenne par Thread: veut[0] et veut[1] n Ti signale quil désire exécuter sa CritSect par: veut[i] =vrai n Mais il nentre pas si lautre est aussi intéressé! n Exclusion mutuelle ok n Déroulement pas satisfait: n Considérez la séquence: u T0: veut[0] = vrai u T1: veut[1] = vrai F Chaque thread attendra indéfiniment pour exécuter sa CritSect: interblocage Thread Ti: while(true){ veut[i] = vrai; while(veut[j]); CritSect veut[i] = faux; nonCritSect } rien faire

29 Chap. 729 Thread T0: while(true){ veut[0] = vrai; while(veut[1]); CritSect veut[0] = faux; nonCritSect } Thread T1: while(true){ veut[1] = vrai; while(veut[0]); CritSect veut[1] = faux; nonCritSect } Algorithme 2 vue globale T0: veut[0] = vrai T1: veut[1] = vrai interblocage! Après vous, monsieur

30 Chap. 730 Algorithme 3 (dit de Peterson) : bon! combine les deux idées: veut[i]=intention dentrer; tour=à qui le tour n Initialisation: u veut[0] = veut[1] = faux u tour = i ou j n Désir dexécuter CritSect est indiqué par veut[i] = vrai n veut[i] = faux à la sortie Thread Ti: while(true){ veut[i] = vrai; // je veux entrer tour = j; // je donne une chance à lautre while (veut[j] && tour==j); CritSect veut[i] = faux; nonCritSect }

31 Chap. 731 Entrer ou attendre? n Thread Ti attend si: u Lautre veut entrer est cest la chance à lui veut[j]==vrai et tour==j n Un thread Ti peut entrer si: u Lautre ne veut pas entrer ou cest la chance à lui F veut[j]==faux ou tour==i

32 Chap. 732 Thread T0: while(true){ veut[0] = vrai; // T0 veut entrer tour = 1; // T0 donne une chance à T1 while (veut[1]&&tour=1); CritSect veut[0] = faux; // T0 ne veut plus entrer nonCritSect } Thread T1: while(true){ veut[1] = vrai; // T1 veut entrer tour = 0; // T1 donne une chance à 0 while (veut[0]&&tour=0); CritSect veut[1] = faux; // T1 ne veut plus entrer nonCritSect } Algorithme de Peterson vue globale

33 Initialisations possibles n Afin quun premier processus puisse entrer dans CritSec, il faut que le test veut[j]==faux ou tour==i soit vrai la première fois pour un des deux processus. Voici une possibilité: veut[0]=veut[1]=faux //initialisation Maintenant, si T1 ne fait rien, veut[1] reste faux et T0 peut entrer Exercice: Étudier les autres possibilités pour le début. Chap. 7 33

34 Chap. 734 Scénario pour le changement de contrôle Thread T0: … CritSect veut[0] = faux; // T0 ne veut plus entrer … Thread T1: … veut[1] = vrai; // T1 veut entrer tour = 0; // T1 donne une chance à T0 while (veut[0]&&tour=0) ; //test faux, entre (F&&V) … T1 donne une chance à T0 mais T0 a dit quil ne veut pas entrer. T1 entre donc dans CritSect

35 Chap. 735 Autre scénario de changem. de contrôle Thread T0: CritSect veut[0] = faux; // T0 ne veut plus entrer nonCritSect veut[0] = vrai; // T0 veut entrer tour = 1; // T0 donne une chance à T1 while (veut[1]==vrai&& tour=1) ; // test vrai, nentre pas (V&&V) Thread T1: veut[1] = vrai; // T1 veut entrer tour = 0; // T1 donne une chance à T0 // mais T0 annule cette action while (veut[0]&&tour=0) ; //test faux, entre (V&&F) T0 veut rentrer mais est obligé à donner une chance à T1, qui entre

36 Chap. 736 Mais avec un petit décalage, cest encore T0! Thread T0: CritSect veut[0] = faux; // 0 ne veut plus entrer nonCritSect veut[0] = vrai; // 0 veut entrer tour = 1; // 0 donne une chance à 1 // mais T1 annule cette action while (veut[1] && tour=1) ; // test faux, entre (V&&F) Thread T1: veut[1] = vrai; // 1 veut entrer tour = 0; // 1 donne une chance à 0 while (veut[0]&&tour=0); // test vrai, nentre pas Si T0 et T1 tentent simultanément dentrer dans CritSect, seule une valeur pour tour survivra: non-déterminisme (on ne sait pas qui gagnera), mais lexclusion fonctionne

37 Chap. 737 Noblige pas une tâche d attendre pour dautres qui pourraient ne pas avoir besoin de la CritSect Supposons que T0 soit le seul à avoir besoin de la CritSect, ou que T1 soit lent à agir: T0 peut rentrer de suite ( veut[1]==faux la dernière fois que T1 est sorti) veut[0] = vrai // prend linitiative tour = 1 // donne une chance à lautre while veut[1] && tour=1 // veut[1]=faux, test faux, entre CritSect veut[0] = faux // donne une chance à lautre Cette propriété est désirable, mais peut causer famine pour T1 sil est lent (condition de course, race condition)

38 Chap. 738 Algorithme 3: preuve de validité (pas matière dexamen, seulement pour les intéressés…) n Exclusion mutuelle est assurée car: u T0 et T1 sont tous deux dans CritSect seulement si tour est simultanément égal à 0 et 1 (impossible) n Démontrons que déroulement est satisfaits: u Ti ne peut pas entrer dans CritSect seulement si en attente dans la boucle while avec condition: veut[j] == vrai et tour = j. u Si Tj ne veut pas entrer dans CritSect alors veut[j] = faux et Ti peut entrer dans CritSect

39 Chap. 739 Algorithme 3: preuve de validité (cont.) u Si Tj a effectué veut[j]=vrai et se trouve dans le while, alors tour==i ou tour==j u Si F tour==i, alors Ti entre dans CritSect. F tour==j alors Tj entre dans CritSect mais il fera veut[j] =faux à la sortie: permettant à Ti dentrer CritSect u mais si Tj a le temps de faire veut[j]=true, il devra aussi faire tour=i u Puisque Ti ne peut modifier tour lorsque dans le while, Ti entrera CritSect après au plus une entrée dans CritSect par Tj (attente limitée)

40 Différence importante n Qelle est la différence importante entre Algo 1 et 3? u Avec lAlgo 1, tous les processus (interessés ou non) doivent entrer et sortir de leur SC en tour F Violation de lexigence de déroulement u Avec lAlgo 3, les procs qui ne sont pas intéressés laissent veut = faux et sont libres de faire autres choses Chap. 740

41 Exemple de faute possible Thread Ti: while (true) { veut[i] = vrai; // je veux entrer tour = j; // je donne une chance à lautre do while (veut[i] && tour==j); SC veut[i] = faux; SR } n Cette solution implémente correctement la SC u Un seul proc à la fois peut entrer n Mais elle viole le déroulement u veut[i] = faux naffecte pas Tj car Tj ne teste pas veut[i] u Tj doit attendre que Ti fasse tour=j après quil a fait tour=i, ce qui pourrait ne jamais se vérifier Chap. 741

42 Chap. 742 A propos de léchec des threads n Si une solution satisfait les critères dExclMutuelle et déroulement, elle procure une robustesse face à léchec dun thread dans sa nonCritSect u un thread qui échoue dans sa nonCritSect est comme un thread qui ne demande jamais dentrer... n Par contre, aucune solution valide ne procure une robustesse face à l'échec dun thread dans sa section critique (CritSect) u un thread Ti qui échoue dans sa CritSect nenvoie pas de signal aux autres threads: pour eux Ti est encore dans sa CritSect... u solution: temporisation. Un thread qui a la SC après un certain temps est interrompu par le SE

43 Chap. 743 Extension à >2 threads n L algorithme de Peterson peut être généralisé au cas de >2 threads u n Cependant, dans ce cas il y a des algorithmes plus élégants, comme lalgorithme du boulanger, basée sur lidée de prendre un numéro au comptoir... u Pas le temps den parler …

44 Chap. 744 Une leçon à retenir… n Afin que des threads avec des variables partagées puissent réussir, il est nécessaire que tous les threads impliqués utilisent le même algorithme de coordination u Un protocole commun

45 Chap. 745 Critique des solutions par logiciel n Difficiles à programmer! Et à comprendre! u Les solutions que nous verrons dorénavant sont toutes basées sur lexistence dinstructions spécialisées, qui facilitent le travail. n Les threads qui requièrent lentrée dans leur CritSect sont actifs à attendre-busy waiting); consommant ainsi du temps de processeur u Pour de longues sections critiques, il serait préférable de bloquer les threads qui doivent attendre... F Rappel: scrutation, polling contre interruption

46 Chap. 746 Solutions matérielles: désactivation des interruptions n Si plusieurs UCT: exclusion mutuelle nest pas préservée u Donc pas bon en général Thread Pi: while(true){ désactiver interrupt CritSect rétablir interrupt nonCritSect }

47 Chap. 747 Solutions matérielles: instructions machine spécialisées n Normal: pendant quun thread ou processus fait accès à une adresse de mémoire, aucun autre ne peut faire accès à la même adresse en même temps n Extension: instructions machine exécutant plusieurs actions (ex: lecture et écriture) sur la même case de mémoire de manière indivisible n Une instruction indivisible ne peut être exécutée que par un thread à la fois (même en présence de plusieurs processeurs)

48 Chap. 748 Linstruction test-and-set n Une version C de test- and-set: n Un algorithme utilisant testset pour Exclusion Mutuelle: n Variable partagée b est initialisée à 0 n Le 1er Pi qui met b à 1 entre dans CritSect n Les autres trouvent b à 1, nentrent pas bool testset(int& i) { if (i==0) { i=1; return true; } else { return false; } Tâche Pi: while testset(b)==false ; CritSect //entre quand vrai b=0; nonCritSect Instruction indivisible!

49 Chap. 749 Quand un proc Pi cherche dentrer: Si la SC est occupée, i=1, testset(b)=faux et Pi reste en attente Si la SC est libre, i=0, il est tout de suite mis à 1 mais testset(b)=vrai et Pi peut entrer

50 Chap. 750 Linstruction test-and-set (cont.) n Exclusion mutuelle est assurée: si Ti entre dans CritSect, lautre Tj est actif à attendre n Problème: utilise encore actif à attendre n Peut procurer facilement lexclusion mutuelle mais nécessite algorithmes plus complexes pour satisfaire les autres exigences du problème de la section critique n Lorsque Ti sort de CritSect, la sélection du Tj qui entrera dans CritSect est arbitraire: pas de limite sur lattente: possibilité de famine

51 Chap. 751 Instruction Échange (Swap) n Certains UCTs (ex: Pentium) offrent une instruction xchg(a,b) qui interchange le contenue de a et b de manière indivisible. n Mais xchg(a,b) souffre des même problèmes que test-and-set

52 Chap. 752 Utilisation de xchg pour exclusion mutuelle (Stallings) n Variable partagée b est initialisée à 0 n Chaque Ti possède une variable locale k n Le Ti pouvant entrer dans CritSect est celui qui trouve b=0 n Ce Ti exclut tous les autres en assignant b à 1 u Quand CritSect est occupée, k et b seront 1 pour un autre thread qui cherche à entrer u Mais k est 0 pour le thread qui est dans la CritSect Thread Ti: while(true){ k = 1 while k!=0 xchg(k,b); CritSect xchg(k,b); nonCritSect } usage: indivisible

53 Chap. 753 Solutions basées sur des instructions fournies par le SE (appels du système) n Les solutions vues jusquà présent sont difficiles à programmer n On voudrait aussi qu`il soit plus facile déviter des erreurs communes, comme interblocages, famine, etc. u Besoin dinstruction à plus haut niveau n Les méthodes que nous verrons dorénavant utilisent des instructions puissantes, qui sont implantées par des appels au SE (system calls)

54 Chap. 754 Sémaphores n Un sémaphore S est un entier qui, sauf pour l'Initialisation, est accessible seulement par ces 2 opérations indivisibles et mutuellement exclusives: u acquire(S) u release(S) n Il est partagé entre tous les threads qui s`intéressent à la même CritSect n Les sémaphores seront présentés en deux étapes: u sémaphores qui sont actifs à attendre F Scrutation u sémaphores qui utilisent interruptions et files d attente

55 Chap. 755 Spinlocks dUnix: Sémaphores occupés à attendre (busy waiting) n La façon la plus simple dimplanter les sémaphores. n Utiles pour des situations où lattente est brève, ou il y a beaucoup dUCTs n S est un entier initialisé à une valeur positive, afin quun premier thread puisse entrer dans la CritSect n Quand S>0, jusquà n threads peuvent entrer n S ne peut jamais être négatif acquire(S): while S=0 ; S--; release(S): S++; Attend si no. de threads qui peuvent entrer = 0 Augmente de 1 le no des threads qui peuvent entrer

56 Chap. 756 Indivisibilité Acquire : La séquence test- décrément est indivisible, mais pas la boucle! Release est indivisible. Rappel: les sections indivisibles ne peuvent pas être exécutées simultanément par différent threads (ceci peut être obtenu en utilisant un des mécanismes précédents) S = 0 indivisible S - - F V CritSect IMPORTANT

57 Chap. 757 Indivisibilité et atomicité S = 0 atomique S - - F V S++ La boucle peut être interrompue pour permettre à un autre thread dinterrompre lattente quand lautre thread sort de la CritSect interruptible autre thr. CritSect (Autre thread)

58 Chap. 758 Thread T1: while(true){ acquire(S); CritSect release(S); nonCritSect } Thread T2: while(true){ acquire(S); CritSect release(S); nonCritSect } Semaphores: vue globale Initialise S à > =1 Peut être facilement généralisé à plus. threads

59 Chap. 759 Utilisation des sémaphores pour sections critiques n Pour n threads n Initialiser S à 1 n Alors 1 seul thread peut être dans sa CritSect n Pour permettre à k threads dexécuter CritSect, initialiser S à k Thread Ti: while(true){ acquire(S); CritSect release(S); nonCritSect }

60 Chap. 760 Utilisation des sémaphores pour synchronisation de threads n On a 2 threads n P1 dans le premier thread doit être exécuté avant P2 dans le deuxième n Définissons un sémaphore S n Initialisons S à 0 P1 P2 P1; release(S) acquire(S); P2

61 Chap. 761 Interblocage et famine avec les sémaphores n Famine: un thread peut narriver jamais à exécuter car il ne teste jamais le sémaphore au bon moment n Interblocage: Supposons S et Q initialisés à 1 u Ils seront 0 au deuxième acquire T0 T1 acquire(S) acquire(Q) acquire(Q) acquire(S)

62 Chap. 762 Sémaphores: observations n Quand S >= 0: u Le nombre de threads qui peuvent exécuter acquire(S) sans devenir bloqués = S F S threads peuvent entrer dans la CritSect F noter puissance par rapport à mécanismes déjà vus F dans les solutions où S peut être > 1 il faudra avoir un 2ème sém. pour les faire entrer un à la fois (excl. mutuelle) n Quand S devient > 1, le thread qui entre le premier dans la CritSect est le premier à tester S (choix aléatoire) u Famine possible F Ceci ne sera plus vrai dans la solution suivante acquire(S): while S=0 ; S--;

63 Chap. 763 Comment éviter lattente occupée et le choix aléatoire dans les sémaphores n Quand un thread doit attendre quun sémaphore devienne plus grand que 0, il est mis dans une file dattente de threads qui attendent sur le même sémaphore n Les files peuvent être PAPS (FIFO), avec priorités, etc. Le SE contrôle l`ordre dans lequel les threads entrent dans leur CritSect n acquire et release sont des appels au système comme les appels à des opérations dE/S n Il y a une file d attente pour chaque sémaphore comme il y a une file dattente pour chaque unité dE/S

64 Chap. 764 Sémaphores sans attente occupée n Un sémaphore S devient une structure de données: u S.value: Une valeur: nombre de processus pouvant entrer u S.list Une liste dattente acquire(S): bloque thread qui effectue lopération et lajoute à la liste S.list release(S) enlève (selon une politique juste, ex: PAPS/FIFO) un thread de S.list et le place sur la liste des threads prêts/ready. un tel sémaphore est associé à une liste dattente comme un disque, une imprimante, etc.

65 Chap. 765 Implementation (les boîtes représentent des séquences atomiques) acquire(S):S.value --; if S.value < 0 { // CritSect occupée add this thread to S.list; block // thread mis en état attente (wait) } release(S): S.value ++; if S.value 0 { // des threads attendent remove a thread P from S.list; wakeup(P) // thread choisi devient prêt } S.value doit être initialisé à une valeur non-négative (dépendant de lapplication, v. exemples)

66 Chap. 766 Figure montrant la relation entre le contenu de la file et la valeur de S (la séquence montrée nest pas contigüe) S > 0: n threads peuvent entrer S 0: aucun thread ne peut entrer et le nombre de threads qui attendent sur S est = |S| Stallings

67 Chap. 767 acquire et release contiennent elles mêmes des CritSect! n Les opérations acquire et release doivent être exécutées de manière indivisible (un seul thr. à la fois) n Dans un système avec 1 seule UCT, ceci peut être obtenu en inhibant les interruptions quand un thread exécute ces opérations n Normalement, nous devons utiliser un des mécanismes vus avant u instructions spéciales, algorithme de Peterson, etc. n Lattente occupée dans ce cas ne sera pas trop onéreuse car acquire et release sont brefs

68 Exercice n Avec cette solution, on peut effectivement éviter la famine! n Expliquez pourquoi et comment Chap. 768

69 Chap. 769 Problèmes classiques de synchronisation n Tampon borné (producteur-consommateur) n Écrivains - Lecteurs n Les philosophes mangeant

70 Chap. 770 Le pb du producteur - consommateur n Un problème classique dans l étude des threads communicants u un thread producteur produit des données (p.ex.des enregistrements d un fichier) pour un thread consommateur

71 Chap. 771 Tampons de communication Prod Cons 1 donn Prod Cons 1 donn Si le tampon est de longueur 1, le producteur et consommateur doivent forcement aller à la même vitesse Des tampons de longueur plus grandes permettent une certaine indépendance. P.ex. à droite le consommateur a été plus lent

72 Chap. 772 Le tampon borné (bounded buffer) une structure de données fondamentale dans les SE b[0] b[1] b[7]b[2] b[6]b[3] b[4]b[5] ou out: 1ère pos. pleine in: 1ère pos. libre b[0] b[1]b[7]b[2]b[6]b[3]b[4]b[5] in: 1ère pos. libre out: 1ère pos. pleine bleu: plein, blanc: libre Le tampon borné se trouve dans la mémoire partagée entre consommateur et usager

73 Chap. 773 Pb de sync entre threads pour le tampon borné n Étant donné que le prod et le consommateur sont des threads indépendants, des problèmes pourraient se produire en permettant accès simultané au tampon n Les sémaphores peuvent résoudre ce problème

74 Chap. 774 Sémaphores: rappel n Soit S un sémaphore sur une CritSect u il est associé à une file d attente u S > 0 : S threads peuvent entrer dans CritSect u S = 0 : aucun thread ne peut entrer, aucun thread en attente u S < 0 : |S| thread dans file d attente n acquire(S): S - - u si avant S > 0, ce thread peut entrer dans CritSect u si avant S <= 0, ce thread est mis dans file d attente u release(S): S++ u si avant S < 0, il y avait des threads en attente, et un thread est réveillé u si avant S >= 0, rien (mais un proc de plus pourra entrer) u Indivisibilité de ces ops

75 Pensez à un petit entrepôt n Ceux qui veulent y apporter des choses, doivent avant tout savoir sil y a de lespace u Un sémaphore E dit combien despace dispo: F Producteur peut entrer si et seulement si il y en a n Ceux qui veulent en retirer des choses, doivent avant tout savoir sil y en a à retirer u Un sémaphore F qui dit combien déléments disponibles: F Consommateur peut entrer si et seulement si il y en a n Une seule personne peut y travailler à un moment donné u Un sémaphore M dit sil y a quelquun dans lentrepôt F Occupé ou libre Chap. 775

76 Chap. 776 Autrement dit … n Un sémaphore E pour synchroniser producteur et consommateur sur le nombre despaces libres n Un sémaphore F pour synchroniser producteur et consommateur sur le nombre déléments consommables dans le tampon n Un sémaphore M pour exclusion mutuelle sur laccès au tampon u Les sémaphores suivants ne font pas lExMut

77 Chap. 777 Solution de P/C: tampon circulaire fini de dimension k Initialization: M.count=1; //excl. mut. F.count=0; //esp. pleins E.count=k; //esp. vides Producteur: while(true){ produce v; acquire(E); acquire(M); ajouter(v); release(M); release(F); } Consommateur: while(true) acquire(F); acquire(M); retirer(); release(M); release(E); consume(w); } Sections Critiques ajouter(v): b[in]=v; In ++ mod k; retirer(): w=b[out]; Out ++ mod k; return w;

78 Chap. 778 Points intéressants à étudier n Dégâts possibles en inter changeant les instructions sur les sémaphores u ou en changeant leur initialisation n Généralisation au cas de plus. prods et cons

79 Chap. 779 Concepts importants de cette partie du Chap 7 n Le problème de la section critique n Lentrelacement et lindivisibilité n Problèmes de famine et interblocage n Solutions logiciel n Instructions matériel n Sémaphores occupés ou avec files n Fonctionnement des différentes solutions n Lexemple du tampon borné n Par rapport au manuel: ce que nous navons pas vu en classe vous le verrez au lab

80 Chap. 780 Glossaire: atomicité n Atomicité, non-interruptibilité: u Le mot atomique a été utilisé dans son sens original grec: a- tomos = non-divisible F Faut pas se faire dérouter par le fait que les atomes dans la physique moderne sont divisibles en électrons, protons, etc. … u La définition précise datomicité, non-déterminisme etc. est un peu compliquée, et il y en a aussi des différentes… (faites une recherche Web sur ces mot clé) u Ce que nous discutons dans ce cours est un concept intuitif: une séquence dops est atomique si elle est exécutée toujours du début à la fin sans aucune interruption ni autres séquences en parallèle

81 Chap. 781 Non-déterminisme et conditions de course n Non-déterminisme: une situation dans laquelle il y a plusieurs séquences dopérations possibles à un certain moment, même avec les mêmes données. Ces différentes séquences peuvent conduire à des résultats différents n Conditions de course: Les situations dans lesquelles des activités exécutées en parallèle sont en course les unes contre les autres pour l`accès à des ressources (variables partagées, etc.), sont appelées conditions de course.

82 Chap. 782 Thread, processus n Les termes thread, process, sont presque équivalents dans ce contexte n Tout ce que nous avons dit au sujet de threads concurrent est aussi valable pour processus concurrents

83 Chap. 783 Différents noms pour acquire, release n Acquire, release ont eté appelés des noms différents n Leur inventeur (Dijkstra) les appelait P, V (provenant de mots en Hollandais …) n Dautres auteurs les appellent wait, signal n Etc.

84 Chap. 784 Sémaphores binaires n Dans les sémaphores binaires, la variable ne peut être que 0 ou 1 n P.ex. le sémaphore S dans le producteur- consommateur est binaire n On a prouvé en théorie que tout pb de synchro peut être résolu utilisant seulement des sémaphores binaires, v. manuel

85 Chap. 785 Difficulté des problèmes de synchronisation n Les problèmes et solutions qui se trouvent dans létude du parallélisme et de la répartition sont entre les plus complexes de linformatique n Car les programmes parallèles ont un comportement mutuel imprévisible dans le temps n Beaucoup de concepts complexes de math, physique etc. peuvent entrer en considération n Heureusement, les langages de programmation comme Java nous cachent cette complexité n Mais pas complètement … les systèmes répartis sont sujets à des pannes imprévisibles u dues à des conditions de temporisation non prévues


Télécharger ppt "Chap. 71 Synchronisation de Processus (ou threads, ou fils ou tâches) Chapitre 7"

Présentations similaires


Annonces Google