Synchronisation de Processus ou de threads fils ou

  • Slides: 108
Download presentation
Synchronisation de Processus (ou de threads, fils ou tâches) Chapitre 7 http: //w 3.

Synchronisation de Processus (ou de threads, fils ou tâches) Chapitre 7 http: //w 3. uqo. ca/luigi/ Chap. 7 1

Le problème Chap. 7 2

Le problème Chap. 7 2

Problèmes avec concurrence = parallélisme n Les threads concurrents doivent parfois partager données (fichiers

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

Exemple 1 n n n Deux threads exécutent cette même procédure et partagent la

Exemple 1 n n n Deux threads exécutent cette même procédure et partagent la même base de données Ils peuvent être interrompus n’importe où Le résultat de l ’exécution concurrente de P 1 et P 2 dépend de l`ordre de leur entrelacement u Chap. 7 Souvent bon, parfois mauvais M. X demande une réservation d’avion Base de données dit que fauteuil A est disponible Fauteuil A est assigné à X et marqué occupé 4

Vue globale d’un «mauvais» entrelacement P 2 P 1 M. Leblanc demande une réservation

Vue globale d’un «mauvais» entrelacement P 2 P 1 M. Leblanc demande une réservation d’avion Interruption ou retard M. Guy demande une réservation d’avion Base de données dit que fauteuil 30 A est disponible Fauteuil 30 A est assigné à Leblanc et marqué occupé Chap. 7 Base de données dit que fauteuil 30 A est disponible Fauteuil 30 A est assigné à Guy et marqué occupé 5

Hypothèse de partage de données Partagées entre threads Chap. 7 Les données partagées ne

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

Exemple 2 n Cas pratique: u Deux threads qui mettent à jour un seul

Exemple 2 n Cas pratique: u Deux threads qui mettent à jour un seul compteur d’accès à une page web n Exécuter en parallèle avec lui-même le code suivant: b=a b++ a=b n Quel pourrait être le résultat final dans a? 7

Deux opérations en parallèle var a partagée entre thread var b est privée à

Deux opérations en parallèle var a partagée entre thread var b est privée à chaque thread P 1 b=a b++ a=b interruption P 2 b=a b++ a=b Supposons que a soit 0 au début P 1 travaille sur son propre b donc le résultat final sera a=1. Mais il pourrait y avoir des cas où le résultat sera correct! Chap. 7 8

3ème exemple Thread P 1 Thread P 2 static char a; void echo() {

3ème exemple Thread P 1 Thread P 2 static char a; void echo() { cin >> a; cout << a; } Chap. 7 Si la var a est partagée, le premier a est effacé Si elle est privée, l’ordre d’affichage est renversé 9

Asynchronie des threads n n Quand plusieurs threads exécutent en parallèle, nous ne pouvons

Asynchronie des threads n n Quand plusieurs threads exécutent en parallèle, nous ne pouvons pas faire d’hypothèses sur la vitesse d’exécution des threads, ni leur entrelacement Peuvent être différents à chaque exécution du programme u Dont le non-déterminisme Chap. 7 10

Autres exemples n n Chap. 7 Des threads qui travaillent en simultanéité sur une

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

Exercice n n n Dans un langage de programmation qui supporte la progr. parallèle,

Exercice n n n Dans un langage de programmation qui supporte la progr. parallèle, écrire un programme avec deux boucles en parallèle Une boucle ne fait qu’afficher des A Une autre boucle ne fait qu’afficher des B À l’écran, vous devriez voir des A et des Bs parsemés de manière aléatoire Pour voir bien ce résultat il pourrait être nécessaire d’inclure un ‘retard’ dans chaque boucle u Sinon, dépendant de l’ordonnanceur, vous pourriez voir p. ex. 1000 fois A avant de voir le premier B u n Chap. 7 P. ex. en Java utiliser méthode Tread. sleep ce qui n’est pas très facile, voir aide dans le www Ceux qui réussissent à faire ceci, SVP venez me voir … 12

Section Critique n Partie d’un processus dont l’exécution ne doit pas entrelacer avec autres

Section Critique n Partie d’un processus dont l’exécution ne doit pas entrelacer avec autres processus u Indivisibilité de la section critique n Une fois qu’un 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 Chap. 7 La section critique doit être verrouillée afin de devenir indivisible 13

Entrelacement de threads A et B A Contin. B contin A Contin. Les flèches

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

Indivisibilité de threads A et B par effet du verrou A B OU B

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

Section critique verrouillée: contrôler que ceci évite le pb M. X demande une réservation

Section critique verrouillée: contrôler que ceci évite le pb M. X demande une réservation d’avion Base de données dit que fauteuil A est disponible indivisible Fauteuil A est assigné à X et marqué occupé Chap. 7 16

Le « mauvais » entrelacement n’est pas possible P 1 M. Leblanc demande une

Le « mauvais » entrelacement n’est pas possible P 1 M. Leblanc demande une réservation d’avion P 2 M. Guy demande une réservation d’avion Base de données dit que fauteuil 30 A est disponible Fauteuil 30 A est assigné à Guy et marqué occupé Base de données dit que fauteuil 30 A est occupé 17

Le problème de la section critique n n Lorsqu’un thread manipule une donnée (ou

Le problème de la section critique n n Lorsqu’un thread manipule une donnée (ou ressource) partagée avec autres, nous disons qu’il se trouve dans une section critique (associée à cette donnée) Le problème de la section critique est de trouver un algorithme d`exclusion mutuelle de threads dans l`exécution de leur Crit. Sect afin que le résultat de leurs actions ne dépendent pas de l’ordre d’entrelacement de leur exécution (avec un ou plusieurs processeurs) L’exécution des sections critiques doit être mutuellement exclusive et indivisible: à tout instant, un seul thread peut exécuter une Crit. Sect pour une donnée (même lorsqu’il y a plusieurs UCT) Ceci peut être obtenu en plaçant des instructions spéciales au début et à la fin de la Crit. Sect u Chap. 7 Implantation du cadenas 18

Deux simplifications n n Chap. 7 Pour simplifier, parfois nous ferons l’hypothèse qu’il n’y

Deux simplifications n n Chap. 7 Pour simplifier, parfois nous ferons l’hypothèse qu’il n’y a qu’une seule Crit. Sect dans un thread Et nous ne ferons plus distinction entre Crit. Sect pour différentes données 19

Structure d’un programme type n n n Le programme est présenté comme boucle infinie:

Structure d’un programme type n n n Le programme est présenté comme boucle infinie: while(true) Chaque thread doit donc demander une permission avant d’entrer dans une Crit. Sect La section de code qui effectue cette requête est la section d’entrée La section critique est normalement suivie d’une section de sortie (leave Crit. Sect) Le code qui reste est la section non-critique while (true) { enter. Crit. Sect leave. Crit. Sect non. Crit. Sect indivisible } Chap. 7 20

Application (un programme qui répète à jamais) M. X demande une réservation d’avion enter.

Application (un programme qui répète à jamais) M. X demande une réservation d’avion enter. Crit. Sectio n critique Base de données dit que fauteuil A est disponible Fauteuil A est assigné à X et marqué occupé leave. Crit. Sect Chap. 7 21

Exigences pour solutions valides (*) n n n Exclusion Mutuelle u En tout moment,

Exigences pour solutions valides (*) n n n Exclusion Mutuelle u En tout moment, au plus un thread peut être dans une Crit. Sect Déroulement u Une Crit. Sect ne sera donnée qu’à un thread qui attend d’y entrer u Chaque fois qu’une Crit. Sect devient disponible, s’il y a des threads qui l’attendent, un d’eux doit être capable d’y entrer (pas d’interblocage) Attente bornée u Un thread qui attend d’entrer dans une Crit. Sect pourra enfin y entrer (pas de famine) F n Chap. 7 = aucun thread ne peut être exclu à jamais de la Crit. Sect à cause d’autres threads qui la monopolisent Notez la différence entre interblocage et famine 22

Trois types de solutions n n n Chap. 7 Solutions par logiciel u des

Trois types de solutions n n n Chap. 7 Solutions par logiciel u des algorithmes qui n’utilisent pas d`instruction spéciales Solutions fournies par le matériel u s’appuient sur l’existence de certaines instructions (du processeur) spéciales Solutions fournies pas le SE u procure certains appels du système au programmeur Toutes les solutions se basent sur l’indivisibilité de l’accè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. Plus en général, toutes les solutions se basent sur l’existence d’instructions indivisibles, qui fonctionnent comme Sections Critiques de base 23

Solutions par logiciel pur Chap. 7 24

Solutions par logiciel pur Chap. 7 24

Un groupe d’étudiants collabore sur un devoir n Solution 1: u Ils se passent

Un groupe d’étudiants collabore sur un devoir n Solution 1: u Ils se passent la copie du devoir dans un ordre fixe: F Marc, Ahmed, Marie, Marc, Ahmed, Marie … Chap. 7 25

Un groupe d’étudiants collabore sur un devoir n Solution 1: u Ils se passent

Un groupe d’étudiants collabore sur un devoir n Solution 1: u Ils se passent le devoir dans un ordre fixe: F Marc, Ahmed, Marie, Marc, Ahmed, Marie … n Solution 2: u Semblable, mais donner la chance seulement à ceux qui veulent travailler Chap. 7 26

Un groupe d’étudiants collabore sur un devoir n Solution 1: u Un étudiant passe

Un groupe d’étudiants collabore sur un devoir n Solution 1: u Un étudiant passe la copie au prochain dans un ordre fixe: F Marc, Ahmed, Marie, Marc, Ahmed, Marie … n Solution 2: u Semblable, mais donner la chance seulement à ceux qui veulent travailler n Solution 3: u Combiner les idées des solutions précédentes n Chap. 7 Les premières deux solutions ont des problèmes, la troisième fonctionne 27

Solutions par logiciel (pas pratiques, mais intéressantes pour comprendre le pb) n Notation u

Solutions par logiciel (pas pratiques, mais intéressantes pour comprendre le pb) n Notation u Pour simplifier, considérons seulement 2 threads: T 0 et T 1 u Lorsque nous discutons de la tâche Ti, Tj sera toujours l’autre 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 Chap. 7 28

Idée de l’algorithme 1 n Les threads se donnent mutuellement le tour u T

Idée de l’algorithme 1 n Les threads se donnent mutuellement le tour u T 0 T 1… n Réalise l’exclusion mutuelle, mais viole l’exigence du déroulement: u Une Crit. Sect pourra être donnée à des threads qui n’en ont pas besoin u Chap. 7 P. ex. après T 0, T 1 pourrait n’avoir pas besoin d’entrer 29

Algorithme 1: threads se donnent mutuellement le tour n n n La variable partagée

Algorithme 1: threads se donnent mutuellement le tour n n n La variable partagée tour est initialisée à 0 ou 1 La Crit. Sect de Ti est exécutée ssi tour = i Ti est actif à attendre si Tj est dans Crit. Sect. Fonctionne pour l’exclusion mutuelle! Mais exigence du déroulement pas satisfaite car l’exécution des Crit. Sect doit strictement alterner Rien faire Thread Ti: while(true){ while(tour!==i); Crit. Sect tour = j; non. Crit. Sect } T 0 T 1… même si l’un des deux n’est pas intéressé du tout Chap. 7 30

Initialisation de tour à 0 ou 1 Thread T 0: While(true){ while(tour!=0); Crit. Sect

Initialisation de tour à 0 ou 1 Thread T 0: While(true){ while(tour!=0); Crit. Sect tour = 1; non. Crit. Sect } Thread T 1: While(true){ while(tour!=1); Crit. Sect tour = 0; non. Crit. Sect } Rien faire Algorithme 1 vue globale Chap. 7 31

Exemple: supposez que tour=0 au début Thread T 0: while(tour!=0); // premier à entrer

Exemple: supposez que tour=0 au début Thread T 0: while(tour!=0); // premier à entrer Crit. Sect tour = 1; non. Crit. Sect while(tour!=0); // entre quand T 1 finit Crit. Sect tour = 1; non. Crit. Sect etc. . . Chap. 7 Thread T 1: while(tour!=1); // entre quand T 0 finit Crit. Sect tour = 0; non. Crit. Sect etc. . . 32

Généralisation à n threads n Chaque fois, avant qu’un thread puisse rentrer dans la

Généralisation à n threads n Chaque fois, avant qu’un thread puisse rentrer dans la section critique, il lui faut attendre que tous les autres aient eu cette chance! u En claire contradiction avec l’exigence de déroulement F Supposez le cas de 1 000 threads, dont seulement quelques uns sont actifs Chap. 7 33

Cependant, deux avantages: n n Pas d’interblocage Pas de famine u Les deux procs

Cependant, deux avantages: n n Pas d’interblocage Pas de famine u Les deux procs avancent toujours F Se donnant le tour l’un à l’autre Chap. 7 34

Algorithme 2 n L’algorithme 2 prend en compte la critique à l’algorithme 1: u

Algorithme 2 n L’algorithme 2 prend en compte la critique à l’algorithme 1: u Donne la Crit. Sect seulement aux threads qui la veulent n Cependant on ne peut pas permettre à un processus de se redonner systématiquement la Crit. Sec famine pour les autres u Faut que chaque processus qui veut entrer donne une chance à des autres avant d’y entrer Chap. 7 35

Algorithme 2 ou l’excès de courtoisie. . . n n n Une variable Booléenne

Algorithme 2 ou l’excès de courtoisie. . . n n n Une variable Booléenne par Thread: veut[0] et veut[1] Ti signale qu’il désire exécuter sa Crit. Sect par: veut[i] =vrai Mais il n’entre pas si l’autre est aussi intéressé! Exclusion mutuelle ok Déroulement pas satisfait: Considérez la séquence: u T 0: veut[0] = vrai u T 1: veut[1] = vrai F Chap. 7 Thread Ti: while(true){ veut[i] = vrai; while(veut[j]); Crit. Sect veut[i] = faux; non. Crit. Sect } rien faire Chaque thread attendra indéfiniment pour exécuter sa Crit. Sect: interblocage 36

Après vous, monsieur Thread T 0: while(true){ veut[0] = vrai; while(veut[1]); Crit. Sect veut[0]

Après vous, monsieur Thread T 0: while(true){ veut[0] = vrai; while(veut[1]); Crit. Sect veut[0] = faux; non. Crit. Sect } Après vous, monsieur Thread T 1: while(true){ veut[1] = vrai; while(veut[0]); Crit. Sect veut[1] = faux; non. Crit. Sect } Algorithme 2 vue globale T 0: veut[0] = vrai T 1: veut[1] = vrai interblocage! Chap. 7 37

Algorithme 3 (dit de Peterson): bon! combine les deux idées: veut[i]=intention d’entrer; tour=à qui

Algorithme 3 (dit de Peterson): bon! combine les deux idées: veut[i]=intention d’entrer; tour=à qui le tour n Initialisation: u veut[0] = veut[1] = faux u tour = i ou j Thread Ti: while(true){ veut[i] = vrai; // n n je veux entrer tour = j; Désir d’exécuter Crit. Sect est indiqué par veut[i] = vrai // je donne une chance à l’autre while (veut[j] && tour==j); Crit. Sect veut[i] = faux; non. Crit. Sect veut[i] = faux à la sortie } Chap. 7 38

Entrer ou attendre? n Thread Ti doit attendre si: u L’autre veut entrer est

Entrer ou attendre? n Thread Ti doit attendre si: u L’autre veut entrer est c’est le tour à l’autre F n veut[j]==vrai et tour==j Un thread Ti peut entrer si: u L’autre ne veut pas entrer ou c’est la chance à lui F veut[j]==faux ou tour==i Utilisez la logique Booléenne pour contr Chap. 7 39

Thread T 0: while(true){ veut[0] = vrai; Thread T 1: while(true){ veut[1] = vrai;

Thread T 0: while(true){ veut[0] = vrai; Thread T 1: while(true){ veut[1] = vrai; // T 0 veut entrer // T 1 veut entrer tour = 1; tour = 0; // T 0 donne une chance à T 1 // T 1 donne une chance à 0 while (veut[1]&&tour==1); Crit. Sect veut[0] = faux; while (veut[0]&&tour==0); Crit. Sect veut[1] = faux; // T 0 ne veut plus entrer // T 1 ne veut plus entrer non. Crit. Sect } Algorithme de Peterson vue globale Chap. 7 40

Un début – étudier aussi les autres possibilités Thread T 0: while(true){ veut[0] =

Un début – étudier aussi les autres possibilités Thread T 0: while(true){ veut[0] = vrai; // T 0 veut entrer Thread T 1: while(true){ veut[1] = vrai; // T 1 veut entrer tour = 1; // T 0 donne une chance à T 1 tour = 0; // T 1 donne une chance à T 0 while (veut[1]&&tour==1); //tour=0, test faux, T 0 entre Chap. 7 Crit. Sect while (veut[0]&&tour==0); //test vrai, T 1 attend dans boucle 41 41

Scénario pour le changement de contrôle Thread T 0: … Crit. Sect veut[0] =

Scénario pour le changement de contrôle Thread T 0: … Crit. Sect veut[0] = faux; // T 0 ne veut plus entrer … Thread T 1: … veut[1] = vrai; // T 1 veut entrer tour = 0; // T 1 donne une chance à T 0 while (veut[0]&&tour==0) ; //test faux, entre (F&&V) … T 1 donne une chance à T 0 mais T 0 a dit qu’il ne veut pas entrer. T 1 entre donc dans Crit. Sect Chap. 7 42

Autre scénario de changem. de contrôle Thread T 0: Crit. Sect veut[0] = faux;

Autre scénario de changem. de contrôle Thread T 0: Crit. Sect veut[0] = faux; // T 0 ne veut plus entrer non. Crit. Sect veut[0] = vrai; // T 0 veut entrer tour = 1; // T 0 donne une chance à T 1 while (veut[1]==vrai&& tour==1) ; // test vrai, n’entre pas (V&&V) Thread T 1: veut[1] = vrai; // T 1 veut entrer tour = 0; // T 1 donne une chance à T 0 // mais T 0 annule cette action while (veut[0]&&tour==0) ; //test faux, entre (V&&F) T 0 veut rentrer mais est obligé à donner une chance à T 1, qui entre Chap. 7 43

Mais avec un petit décalage, c’est encore T 0! Thread T 0: Thread T

Mais avec un petit décalage, c’est encore T 0! Thread T 0: Thread T 1: Crit. Sect veut[0] = faux; // 0 ne veut plus entrer non. Crit. Sect veut[0] = vrai; // 0 veut entrer tour = 1; // 0 donne une chance à 1 // mais T 1 annule cette action veut[1] = vrai; // 1 veut entrer tour = 0; // 1 donne une chance à 0 while (veut[0]&&tour==0); (veut[1] && tour==1) ; // test faux, entre (V&&F) // test vrai, n’entre pas Chap. 7 Si T 0 et T 1 tentent simultanément d’entrer dans Crit. Sect, seule une valeur pour tour survivra: non-déterminisme (on ne sait pas qui gagnera), mais l’exclusion fonctionne 44

N’oblige pas une tâche d’attendre pour d’autres qui pourraient ne pas avoir besoin de

N’oblige pas une tâche d’attendre pour d’autres qui pourraient ne pas avoir besoin de la Crit. Sect Supposons que T 0 soit le seul à avoir besoin de la Crit. Sect, ou que T 1 soit lent à agir: T 0 peut rentrer de suite (veut[1]==faux la dernière fois que T 1 est sorti) veut[0] = vrai // prend l’initiative tour = 1 // donne une chance à l’autre while veut[1] && tour==1 // veut[1]=faux, test faux, entre Crit. Sect veut[0] = faux // donne une chance à l’autre Cette propriété est désirable, mais peut causer famine pour T 1 s’il est lent (condition de course, race condition) Chap. 7 45

Hypothèse de fond n Il est nécessaire de supposer que seulement une UCT à

Hypothèse de fond n Il est nécessaire de supposer que seulement une UCT à la fois puisse exécuter les affectations aux variables veut et tour, ainsi que le test u Pendant qu’un 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 Chap. 7 46

Différence importante n Qelle est la différence importante entre Algo 1 et 3? u

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

Par rapport aux trois conditions n n On peu prouver que l’algorithme de Peterson

Par rapport aux trois conditions n n On peu prouver que l’algorithme de Peterson satisfait aux trois exigences pour solutions valides mentionnées avant Notamment, un processus qui demande d’entrera ‘la prochaine fois’ u Attente bornée, pas de famine n Chap. 7 V. plus loin dans ces notes 48

Exemple d’algorithme fautif Thread Ti: while (true) { veut[i] = vrai; // je veux

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

Exercice (facile): déterminer si cet algorithme fonctionne Thread Ti: while (true) { veut[i] =

Exercice (facile): déterminer si cet algorithme fonctionne Thread Ti: while (true) { veut[i] = vrai; tour = j; do while (veut[j] && tour==j){veut[j]=faux}; Crit. Sect veut[i] = vrai; non. Crit. Sect } Chap. 7 50

ap. 7 A propos de l’échec des threads n n Si une solution satisfait

ap. 7 A propos de l’échec des threads n n Si une solution satisfait les exigences d’Excl. Mutuelle et déroulement, elle procure une robustesse face à l’échec d’un thread dans sa non. Crit. Sect u un thread qui échoue dans sa non. Crit. Sect est comme un thread qui ne demande jamais d’entrer. . . Par contre, situation difficile si un thread échoue dans la Crit. Sect u un thread Ti qui échoue dans sa Crit. Sect n’envoie pas de signal aux autres threads: pour eux Ti est encore dans sa Crit. Sect. . . u solution: temporisation. Un thread qui a la SC après un certain temps est interrompu par le SE 51

Extension à >2 threads n L ’algorithme de Peterson peut être généralisé au cas

Extension à >2 threads n L ’algorithme de Peterson peut être généralisé au cas de >2 threads u n http: //docs. lib. purdue. edu/cgi/viewcontent. cgi? article=1778&context=cstech Cependant, dans ce cas il y a des algorithmes plus élégants, comme l’algorithme du boulanger, basée sur l’idée de ‘prendre un numéro au comptoir’. . . u Pas le temps d’en parler … Chap. 7 52

Une leçon à retenir… n Afin que des threads avec des variables partagées puissent

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 Chap. 7 53

Critique des solutions par logiciel n Difficiles à programmer! Et à comprendre! u n

Critique des solutions par logiciel n Difficiles à programmer! Et à comprendre! u n Les solutions que nous verrons dorénavant sont toutes basées sur l’existence d’instructions spécialisées, qui facilitent le travail. Les threads qui requièrent l’entrée dans leur Crit. Sect sont actifs à attendre-busy waiting; consommant ainsi du temps de processeur Situation de scrutation (polling) u Pour de longues sections critiques, il serait préférable de bloquer les threads qui doivent attendre. . . F Et de les reveiller quand ils peuvent entrer u • Rappel: scrutation ou interruption • Voir les sémaphores Chap. 7 54

Solutions par matériel Chap. 7 55

Solutions par matériel Chap. 7 55

Solutions matérielles: 1) désactivation des interruptions Thread Pi: while(true){ désactiver interrupt Crit. Sect rétablir

Solutions matérielles: 1) désactivation des interruptions Thread Pi: while(true){ désactiver interrupt Crit. Sect rétablir interrupt non. Crit. Sect } Chap. 7 n Si plusieurs UCT: exclusion mutuelle n’est pas préservée u On ne peut pas désactiver les interruptions sur toutes les UCT en même temps u Donc pas bon en général 56

Solutions matérielles: 2) instructions de machine spécialisées n Fait: Accès exclusif à la mémoire

Solutions matérielles: 2) instructions de machine spécialisées n Fait: Accès exclusif à la mémoire pour les UCT u u n Chap. 7 Une seule UCT à la fois peut faire accès à la mémoire centrale Donc un seul processus ou thread à la fois Ce fait est déjà utilisé dans les solution précédentes, mais peut aussi être utilisé pour des instructions spécialisées, comme la suivante 57

Instruction ‘Échange’ (Swap) n n Plusieurs UCTs (ex: Pentium) offrent une instruction xchg(a, b)

Instruction ‘Échange’ (Swap) n n Plusieurs UCTs (ex: Pentium) offrent une instruction xchg(a, b) qui interchange le contenu de a et b de manière indivisible. u L’instruction entière est exécutée dans un seul cycle de mémoire F Sans possibilité pour autres processus d’exécuter des autres instructions en même temps Chap. 7 58

Utilisation de xchg pour exclusion mutuelle (Stallings) n n Chap. 7 Variable partagée b

Utilisation de xchg pour exclusion mutuelle (Stallings) n n Chap. 7 Variable partagée b est usage: initialisée à 0 Chaque Ti possède une Thread Ti: variable locale ki Un Ti peut entrer dans Crit. Sect while(true){ ki = 1 s’il trouve b==0 while ki==1 xchg(ki, b); Ce Ti exclut les autres en affectant b=1 Crit. Sect u Quand Crit. Sect est occupée, xchg(ki, b); //sortie kj et b seront 1 pour un autre non. Crit. Sect thread qui cherche à entrer } u Mais k est 0 pour le thread qui est dans la Crit. Sect 59

Fonctionnement … b initialisé à 0 Thread T 0: while(true){ k 0 = 1

Fonctionnement … b initialisé à 0 Thread T 0: while(true){ k 0 = 1 while k 0==1 xchg(k 0, b); // la 2ème fois que k 0 est testé il est 0 et donc le test faux; T 0 entre et b==1, k 0==0 Crit. Sect xchg(k 0, b); // b==0, k 0==1 non. Crit. Sect } Thread T 1: while(true){ k 1 = 1 while k 1==1 xchg(k 1, b); // k 1==1 et b==1 continue à échanger k 1 et b // k 1==0; T 1 entre et b==1, k 1==0 T 0 ne peut pas entrer car k 0==1 Crit. Sect xchg(k 1, b); non. Crit. Sect Chap. 7 } //T 0 peut entrer 60

Considérations sur Échange n Si un thread entre dans Crit. Sect, un autre qui

Considérations sur Échange n Si un thread entre dans Crit. Sect, un autre qui voudrait y entrer est actif à attendre u n Lorsque un thread sort de Crit. Sect, le prochain thread qui l’a est le premier qui réussit à exécuter une échange: u Chap. 7 Il boucle en attente de pouvoir exécuter son exch pas de limite sur l’attente pour les processus ‘lents’: possibilité de famine 61

Exercice n Chap. 7 Voir ce qui pourrait se passer si b est initialisée

Exercice n Chap. 7 Voir ce qui pourrait se passer si b est initialisée à 1 62

Sémaphores avec attente occupée Chap. 7 63

Sémaphores avec attente occupée Chap. 7 63

Solutions basées sur des instructions fournies par le SE (appels du système) n n

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

Sémaphores n n n Un sémaphore S est un entier qui, sauf pour l'Initialisation,

Sémaphores n n 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) Il est partagé entre tous les threads qui s`intéressent à la même Crit. Sect 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 Chap. 7 d ’attente 65

Spinlocks d’Unix-Linux: Sémaphores occupés à attendre (busy waiting) n n n La façon la

Spinlocks d’Unix-Linux: Sémaphores occupés à attendre (busy waiting) n n n La façon la plus simple d’implanter les sémaphores. Utiles pour des situations où l’attente est brève, ou il y a beaucoup d’UCTs S est un entier initialisé à une valeur positive, afin qu’un premier thread puisse entrer dans la Crit. Sect Quand S>0, jusqu’à S threads peuvent entrer Quand S=0, aucun ne peut entrer S ne peut jamais être négatif acquire(S): while S==0 ; S--; Attend si no. de threads qui peuvent entrer = 0 release(S): S++; Augmente de 1 le no des threads qui peuvent entrer Chap. 7 66

Idée n Une salle avec limites de capacité u Un gardien à la porte

Idée n Une salle avec limites de capacité u Un gardien à la porte compte les personnes qui entrent, laisse entrer seulement si la salle n’est pas pleine F Soustrait 1 d’un compteur quand il laisse entrer quelqu’un F Ajoute 1 au compteur quand quelqu'un sort u Si on veut seul. 1 personne dans la salle, on initialise le compteur à 1 Chap. 7 67

Indivisibilité Acquire: La séquence test-décrément est indivisible mais pas la boucle! IMPORTANT S ==

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

Indivisibilité de acquire, release Crit. Sect S++ interruptible S == 0 autre thr. V

Indivisibilité de acquire, release Crit. Sect S++ interruptible S == 0 autre thr. V F indivisible S-- (Autre thread) Crit. Sect La boucle peut être interrompue pour permettre à un autre thread d’interrompre l’attente quand l’autre thread sort de la Crit. Sect Chap. 7 69

Initialise S à >=1 Thread T 1: while(true){ acquire(S); Crit. Sect release(S); non. Crit.

Initialise S à >=1 Thread T 1: while(true){ acquire(S); Crit. Sect release(S); non. Crit. Sect } Thread T 2: while(true){ acquire(S); Crit. Sect release(S); non. Crit. Sect } Semaphores: vue globale Peut être facilement généralisé à plus. threads Chap. 7 70

Utilisation des sémaphores pour sections critiques n n n Chap. 7 Initialiser S à

Utilisation des sémaphores pour sections critiques n n n Chap. 7 Initialiser S à 1 Alors 1 seul thread peut être dans sa Crit. Sect Pour permettre à k threads d’exécuter Crit. Sect, initialiser S à k Thread Ti: while(true){ acquire(S); Crit. Sect release(S); non. Crit. Sect } 71

Utilisation des sémaphores pour mettre des threads en seq. n n Chap. 7 On

Utilisation des sémaphores pour mettre des threads en seq. n n Chap. 7 On a 2 threads P 1 dans le premier thread doit être exécuté avant P 2 dans le deuxième Définissons deux sémaphores S et T Initialisons S à 1, T à 0 P 1 P 2 acquire(S) P 1; release(T) acquire(T); P 2 72

Famine possible avec les sémaphores spinlocks n Chap. 7 Un thread peut n’arriver jamais

Famine possible avec les sémaphores spinlocks n Chap. 7 Un thread peut n’arriver jamais à exécuter car il ne teste jamais le sémaphore au bon moment 73

Interblocage avec les sémaphores n Interblocage: Supposons S et Q initialisés à 1 Ils

Interblocage avec les sémaphores n Interblocage: Supposons S et Q initialisés à 1 Ils seront 0 au deuxième acquire u Aucun des deux procs ne peut avancer u T 0 T 1 acquire(S) acquire(Q) acquire(S) Chap. 7 74

acquire(S): Sémaphores: observations while S==0 ; S--; n Quand S >= 0: u Le

acquire(S): Sémaphores: observations while S==0 ; S--; 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 Crit. Sect F Puissance par rapport aux mécanismes précédents 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) F n Quand S devient > 1, le premier thread qui entre dans la Crit. Sect est le premier à tester S (choix aléatoire) u Famine possible F Ceci ne sera plus vrai dans la solution suivante Chap. 7 75

Comment éviter l’attente occupée et le choix aléatoire dans les sémaphores n n Chap.

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

Sémaphores avec files d’attente Chap. 7 77

Sémaphores avec files d’attente Chap. 7 77

Idée des sémaphore avec liste d’attente n Pensez à une salle avec limites d’admission

Idée des sémaphore avec liste d’attente n Pensez à une salle avec limites d’admission u Un gardien est à la porte et compte les personnes qui entrent et sortent n Si la salle est pleine: u Avec les spinlocks, une personne qui veut entrer est renvoyée et doit revenir plus tard pour voir s’il y a de la place u Dans les sémaphores avec liste d’attente, une personne qui veut entrer est mise en attente et réveillée quand il y aura de la place Chap. 7 78

Sémaphores avec file d’attente n Un sémaphore S devient une structure de données: u

Sémaphores avec file d’attente n Un sémaphore S devient une structure de données: u u S. value: Une valeur: nombre de processus pouvant entrer S. list Une liste d’attente acquire(S): Si S==0 bloque thread qui effectue l’opération et l’ajoute à la liste S. list Chap. 7 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 peut être associé à une liste d’attente comme un disque, une imprimante, etc. S>0 est un événement qu’un processus doit attendre 79

Implementation (les boîtes représentent des séquences indivisibles) acquire(S): S. value --; si S. value

Implementation (les boîtes représentent des séquences indivisibles) acquire(S): S. value --; si S. value < 0 { // Crit. Sect occupée, thread doit attendre ajouter ce thread à S. list; block // thread mis en état attente (wait) } // si S. value ≥ 0, entrer dans SC release(S): S. value ++; si S. value 0 { // des threads attendent enlever 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 } // en tout cas, sortir de Sc l’application, v. exemples) Chap. 7 80

Figure montrant la relation entre le contenu de la file et la valeur du

Figure montrant la relation entre le contenu de la file et la valeur du sémaphore x (suspended list = liste d’attente) x > 0: x threads peuvent entrer x 0: aucun thread ne peut entrer et le nombre de threads qui attendent sur x (suspended list) est = |x| Chap. 7 Stallings 81

acquire et release contiennent elles mêmes des Crit. Sect! n n Les opérations acquire

acquire et release contiennent elles mêmes des Crit. Sect! n n Les opérations acquire et release doivent être exécutées de manière indivisible (un seul thr. à la fois) Pour faire ça, nous devons utiliser un des mécanismes vus avant P. ex. instruction Exchange u Avec attente occupée u n Chap. 7 L’attente occupée dans ce cas ne sera pas trop onéreuse car acquire et release sont courts 82

Comparaison: spinlocks et sémaphores avec file n Les spinlocks sont préférables quand il y

Comparaison: spinlocks et sémaphores avec file n Les spinlocks sont préférables quand il y a peu de processus en lice pour la ressource et les temps d’attente sont courts u Utilisés pour des attentes courtes dans le noyau n Les sémaphores avec file sont avantageux dans les autres cas u Surtout quand l’ordre est important F NB: dans la terminologie Unix-Linux les spinlocks ne sont pas appelés sémaphores, ils sont appelés seulement ‘spinlocks’ Chap. 7 83

Exercice n n Chap. 7 Avec cette solution, on peut effectivement éviter la famine!

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

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

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

Application: Tampon borné ou producteur-consommateur Chap. 7 86

Application: Tampon borné ou producteur-consommateur Chap. 7 86

Le pb du producteur - consommateur n Un problème classique dans l ’étude des

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 Chap. 7 87

Tampons de communication Prod 1 donn Cons Si le tampon est de longueur 1,

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

Le tampon borné (bounded buffer) une structure de données fondamentale dans les SE in:

Le tampon borné (bounded buffer) une structure de données fondamentale dans les SE in: 1ère pos. libre b[0] b[1] b[7] b[2] b[6] b[3] b[5] b[4] out: 1ère pos. pleine ou b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] 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 Chap. 7 89

Pb de sync entre threads pour le tampon borné n n Chap. 7 Étant

Pb de sync entre threads pour le tampon borné n n Chap. 7 É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 Les sémaphores peuvent résoudre ce problème 90

Sémaphores: rappel n n u Soit S un sémaphore sur une Crit. Sect u

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

Pensez à un petit entrepôt de caisses d’un produit n Ceux qui veulent y

Pensez à un petit entrepôt de caisses d’un produit n Ceux qui veulent y apporter une caisse, doivent avant tout savoir s’il y a de l’espace u Un sémaphore E dit combien d’espace dispo: F n Ceux qui veulent en retirer des caisses, doivent avant tout savoir s’il y en a à retirer u Un sémaphore F qui dit combien de caisses disponibles: F n Consommateur peut entrer si et seulement si il y en a Pour éviter la confusion, une seule personne peut y travailler à un moment donné u Un sémaphore M dit s’il y a quelqu’un dans l’entrepôt F Chap. 7 Producteur peut entrer si et seulement si il y en a Occupé ou libre 92

Autrement dit … n n n Un sémaphore E pour synchroniser producteur et consommateur

Autrement dit … n n n Un sémaphore E pour synchroniser producteur et consommateur sur le nombre d’espaces libres Un sémaphore F pour synchroniser producteur et consommateur sur le nombre d’éléments consommables dans le tampon Un sémaphore M pour exclusion mutuelle sur l’accès au tampon u E et F ne font pas l’Ex. Mut Chap. 7 93

Solution de P/C: tampon circulaire fini de dimension k Initialization: M. count=1; //excl. mut.

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 ajouter(v): b[in]=v; In ++ mod k; retirer(): w=b[out]; Out ++ mod k; return w; Chap. 7 Producteur: while(true){ produce v; acquire(E); acquire(M); ajouter(v); release(M); release(F); } Sections Critiques Consommateur: while(true) acquire(F); acquire(M); retirer(); release(M); release(E); consume(w); } 94

Points intéressants à étudier n Dégâts possibles en inter changeant les instructions sur les

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 Chap. 7 Généralisation au cas de plus. prods et cons 95

Concepts importants de cette partie du Chap 7 n n n n n Chap.

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

Glossaire n Indivisible, atomique, non-interruptible: u Ces mots sont équivalents u Le mot atomique

Glossaire n Indivisible, atomique, non-interruptible: u Ces mots sont équivalents u Le mot atomique est utilisé dans son sens original grec: atomos = indivisible F u u Chap. 7 Faut pas se faire dérouter par le fait que les atomes dans la physique moderne sont divisibles en électrons, protons, etc. … La définition précise de ces concepts est un peu compliquée, et il y en a aussi des différentes… (faites une recherche Web sur ces mot clé) Ce que nous discutons dans ce cours est un concept intuitif: une séquence d’ops est indivisible ou atomique si elle est exécutée toujours du début à la fin sans aucune interruption ni autres séquences en parallèle 97

Non-déterminisme et conditions de course n Non-déterminisme: une situation dans laquelle il y a

Non-déterminisme et conditions de course n Non-déterminisme: une situation dans laquelle il y a plusieurs séquences d’opérations possibles à un certain moment, même avec les mêmes données. u 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 ’ u Chap. 7 Ces différentes séquences peuvent conduire à des résultats différents L’ordre des accès détermine le résultat 98

Thread, processus n n Chap. 7 Les termes thread, process, sont presque équivalents dans

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

Sémaphores binaires n n Chap. 7 Un type particulier de sémaphore Dans les sémaphores

Sémaphores binaires n n Chap. 7 Un type particulier de sémaphore Dans les sémaphores binaires, la variable ne peut être que 0 ou 1 P. ex. le sémaphore S dans le producteurconsommateur est binaire On a prouvé en théorie que tout pb de synchro peut être résolu utilisant seulement des sémaphores binaires 100

Difficulté des problèmes de synchronisation n n Les problèmes et solutions qui se trouvent

Difficulté des problèmes de synchronisation n 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 l’informatique Car les programmes parallèles ont un comportement mutuel imprévisible dans le temps Beaucoup de concepts complexes de math, physique etc. peuvent entrer en considération Heureusement, les langages de programmation comme Java nous cachent cette complexité Mais pas complètement … les systèmes répartis sont sujets à des pannes imprévisibles u Chap. 7 dues à des conditions de temporisation non prévues 101

MATÉRIAUX SUPPLÉMENTAIRES Ch. 6 102

MATÉRIAUX SUPPLÉMENTAIRES Ch. 6 102

Différents noms pour acquire, release n n Chap. 7 Acquire, release ont eté appelés

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

Algorithme 3: preuve de validité (pas matière d’examen, seulement pour les intéressés…) n Exclusion

Algorithme 3: preuve de validité (pas matière d’examen, seulement pour les intéressés…) n Exclusion mutuelle est assurée car: u T 0 et T 1 sont tous deux dans Crit. Sect 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 Crit. Sect seulement si en attente dans la boucle while avec condition: veut[j] == vrai et tour = j. u Si Tj ne veut pas entrer dans Crit. Sect alors veut[j] = faux et Ti peut entrer dans Crit. Sect Chap. 7 104

Algorithme 3: preuve de validité (cont. ) u u Si Tj a effectué veut[j]=vrai

Algorithme 3: preuve de validité (cont. ) u u Si Tj a effectué veut[j]=vrai et se trouve dans le while, alors tour==i ou tour==j Si F F u Si Tj a le temps de faire tant veut[j]=true que tour=i F u Chap. 7 tour==i, alors Ti entre dans Crit. Sect. tour==j alors Tj entre dans Crit. Sect mais il fera veut[j]=faux à la sortie: permettant à Ti d’entrer Crit. Sect Puisque Ti ne peut modifier tour dans le while, Ti entrera Crit. Sect après au plus une entrée dans Crit. Sect par Tj (attente bornée, pas de famine) Cependant il y a encore la possibilité que les deux affectations deviennent séparées dans Tj, et si ceci est systématique on pourrait avoir famine de Tj F V. scénario présenté précédemment, transparent intitulé: « Mais avec un petit décalage, c’est encore T 0! » F Encore une fois, c’est le cas de Tj lent à agir 105

L’instruction test-and-set Un algorithme utilisant testset pour Exclusion n n Une version C de

L’instruction test-and-set Un algorithme utilisant testset pour Exclusion n n Une version C de testand-set: bool testset(int& i) { if (i==0) { return true; i=1; } else { return false; } } n n n Mutuelle: Variable partagée b est initialisée à 0 Le 1 er Pi qui met b à 1 entre dans Crit. Sect Les autres trouvent b à 1, n’entrent pas Tâche Pi: while testset(b)==false ; Crit. Sect //entre quand vrai instructions critiques. . . b=0; //sortie de CS non. Crit. Sect Instruction indivisible! Chap. 7 106

Quand un proc Pi cherche d’entrer: • Si la SC est occupée, • i=1,

Quand un proc Pi cherche d’entrer: • 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 Chap. 7 107

Parallélisme dans la programmation fonctionnelle n Dans la programmation fonctionnelle, le parallélisme vient naturel

Parallélisme dans la programmation fonctionnelle n Dans la programmation fonctionnelle, le parallélisme vient naturel sans besoin d’artifices: u y = g(f(x, y), h(z)) F Pour calculer y, la fonction g lance en parallèle les fonctions f et h qui n’ont pas besoin de communiquer l’une avec l’autre n Chap. 7 Cependant la programmation purement fonctionnelle est peu utilisée pour des raisons pratiques 108