ARCHITECTURE des SYSTEMES INFORMATIQUES 1 Cours B4 Processus...
Architecture des Systèmes 2 Historique Architecture d'un Ordinateur / d'un processeur Objectif et rôle d'un Système d'exploitation Notions de base / Mécanismes fondamentaux Entrées / Sorties Les Processus Ordonnancement La Mémoire Mesures de performances Les standards Et l'avenir...?
Les Processus 3 Définition (déjà vue) Représentation Interactions Synchronisation Etude de l'implémentation sous Unix/linux
Représentations d'un processus 4 Une modélisation des processus nous permettra d'analyser leur comportement, et donc d'en Vérifier le bon fonctionnement Détecter les problèmes tels que blocages tirer des algorithmes de gestion.... Différents modèles existes : Systèmes de tâches et précédence Automates Réseaux de Pétri Réseaux colorés...
Système de tâches 5 Un processus va être décomposé en N tâches élémentaires P = suite de Tâches = T 1 T 2,... T n Chaque tâche est ensuite décomposée en 3 éléments : L'événement d, qui correspond à une phase d'initialisation : exemple : lecture d'une valeur en mémoire. Le corps de la tâche : opération sans interaction avec l'extérieur => ne sera pas considéré. L'événement f, qui correspond à une phase de fin de tâche : exemple écriture d'une valeur dans un registre Donc pour un processus séquentiel: P = T 1 T 2,... T n = d 1 f 1 d 2 f 2...d n f n
Graphe de précédence 6 Dès qu'un processus n'est plus simplement séquentiel, la simple connaissance de la liste des tâches ne suffit plus. Notion de précédence, c'est à dire d'ordre d'exécution. Notation sous forme de graphe : (exemple tjrs séquentiel) T 1 T 2 T 3 Lorsque le graphe est sans redondance, (plus petite relation), c'est le «graphe de précédence»
Processus avec parallélisme 7 Quand des tâches sont indépendantes au sein d'un processus, le graphe devient non séquentiel : T 1 T 2 T 3 T1 est une tâche initiale. T4 est une tâche terminale T2 et T3 sont indépendantes. T 4
Un peu de formalisme 8 Alphabet = ensemble des événements qui constituent le processus A = {d1, f1, d2, f2,...dn,fn} Mot = description temporelle de la suite des événements de cet alphabet. pour l'exemple précédent : m1 = {d1 f1 d2 d3 f2 f3 d4 f4} m2 = {d1 f1 d2 f2 d3 f3 d4 f4} sont deux mots décrivant deux comportements possibles Langage = ensemble de tous les mots possibles associés à un graphe de précédence donné.
Notation de la relation de précédence 9 on note E l'ensemble des tâches du processus P, et «<» le relation de précédence : Ti < Tj veut dire simplement que Ti doit précéder Tj Cette relation a certaines propriétés : On ne peut avoir T < T On ne peut avoir à la fois T1 < T2 et T2 < T1 Elle est transitive : T1 < T2 et T2 < T3 => T1 < T3 Le système de tâche est l'ensemble (E, <)
Combinaison de systèmes de tâches 10 On appelle produit de deux systèmes l'exécution séquentielle de ces deux systèmes On doit relier toutes les tâches terminales du premier, à toutes les tâches initiales du second : T 1 T 1 T 6 T 7 T 2 T 3 T 2 T 3 X = T 4 T 5 T 8 T 4 T 5 T 6 T 7 T 8
Combinaison de systèmes de tâches (2) 11 La combinaison parallèle de deux systèmes s'obtient facilement en juxtaposant les deux : il n'y a aucun liens entre les deux Pour un produit de 2 systèmes, le Langage résultant est la simple concaténation des deux langages, mot par mot pris deux à deux. Pour la combinaison parallèle, le langage résultant est plus difficile à obtenir.
Application à l'étude des systèmes 12 Ce modèle nous permettra d'étudier trois aspects de l'interaction de processus : Vérifier si le système est déterminé, c'est à dire si deux exécutions différentes, à partir des même conditions initiales, donnent toujours le même résultat. Déterminer le graphe de parallélisme maximal Détecter les blocages potentiels.
Exemple 13 Soit le système suivant : T1 : X=read(5) T2 : X=X+Z T3 : Print Y T4 : Z=read(7) T5 : Y=X+Z Pour les mots d1 f1 d4 f4 d2 f2 d5 f5 d3 f3 on obtient l'affichage Y=19 d1 d4 f1 f4 d2 d5 f2 f5 d3 f3 Affichage Y= 12 Le système est non déterminé, donc inexploitable. T 1 T 2 T 3 T 4 T 5
Système déterminé 14 On introduit d'abord la notion d'état du système avec la grandeur M = ensemble de la mémoire utilisé par les processus. Un système est donc dit déterminé si : Pour une valeur définie M0. m Langage(S); S = système (E,<) L'état final M est le même. On peut aussi introduire les références suivantes Li = domaine de lecture de la tâche i = ensemble des cellules mémoire lues par la tâche, pendant l'événement d i, donc Ei = domaine d'écriture de la tâche i = ensemble des cellules mémoire modifiées par la tâche, pendant l'événement f i, donc
Système déterminé (2) 15 On introduit la notion de tâches non interférentes : T1 et T2 sont non-interférentes entre elles si : T1<T2 ou T2<T1 Ou : L1 E2 = L2 E1 = E1 E2 =. = Conditions de Bernstein Si un système est constitué de taches 2 à 2 noninterférentes, il est déterminé, ce qui est le but à atteindre.
Reprenons l'exemple 16 T1 : X=read(5) T2 : X=X+Z T3 : Print Y T4 : Z=read(7) T5 : Y=X+Z On voit clairement que : T1 et T5 sont interférentes T2 et T4 de même T2 et T5 aussi T5 et T3 Si on impose T2 < T5, le graphe déterminé devient : T 1 T 2 T 1 T 2 T 3 T 4 T 4 T 5 T 5 T 3
Parallélisme maximal 17 Le but est de réduire au mieux un système de tâches, de façon à avoir le plus grand parallélisme, donc le meilleur taux d'utilisation de la CPU. Il est évident que le système réduit et le système initial doivent donner les même résultats ; c.a.d qu'ils doivent être équivalents : S(E,<) et S'(E, <') sont équivalents s'ils sont tous les 2 déterminés, et si l'état final Mf de la mémoire est le même, pour un même état M 0. Une autre définition impose que la suite des état de la mémoire soit identique dans les 2 cas, mais c'est sans doute trop restrictif.
Parallélisme maximal (2) 18 Un système de tâche sera de parallélisme maximale si : La suppression de tout arc (T, T') du graphe (c.a.d la suppression d'une relation de précédence T<T' ou T'<T), entraîne l'interférence des tâches (T,T'), donc le non-déterminisme du système. Soit de façon plus formelle : (T1<T2 ou T2 < T1) et (L1 E2 ou L2 E1 ou E1 E2 ) et E1 E2 non vides. La technique de construction de ce système minimal consiste à éliminer tous les arcs redondants, c.a.d. la fermeture transitive de la relation <
Exemple de réduction 19 Soit le processus séquentiel suivant P : X=2 Y=F(4) Z = Y+G(7) A= X+Y+5 B= 2*Y+Z = C= (A+B) * Z A += Y D= A+B+C T 1 T 2 T 3 T 4 T 5 T 6 T 8 T 7
Exemple Etape 1 20 Déterminer le tableau des domaines de lecture et écriture Taches \ Variables X Y Z A B C D T1:X=2 E T2:Y=F(4) E T3:Z = Y+G(7) L E T4:A= X+Y+5 L L E T5:B= 2*Y+Z L L E T6:C= (A+B) * Z L L L E T7:A += Y L E/L T8:D= A+B+C L L L E
Exemple Etape -2 21 Lister les interférences : Le tableau est symétrique transversalement Taches T1:X=2 T2:Y=F(4) T3:Z = Y+G(7) T4:A= X+Y+5 T5:B= 2*Y+Z T6:C= (A+B) * Z T7:A += Y T8:D= A+B+C T1 T2 T3 T4 T5 T6 T7 T8
Exemple - Etape 3 22 Déterminer, à partir de ce tableau, les relations à imposer pour éviter des interférences : T1 < T4 T2 < T3, T4, T5, T7 T3 < T5, T6 T4 < T6, T7, T8 T5 < T6, T8 T6 < T7, T8 T7 < T8
Exemple Etape 4 23 Supprimer, dans le graphe séquentiel d'origine, les arcs non essentiels = ceux qui n'entraineront pas d'interférences : T 1 T 1 T 2 T 2 T 3 T 3 T 4 T 4 T 5 T 5 T 6 T 6 T 8 T 7 T 8 T 7
Exemple Etape 5 Ajouter tous les arcs trouvés par l'étude des interférences; Puis, supprimer les arcs redondants = les plus 24 courts! T 1 T 2 T 1 T 2 x x T 3 T 4 x T 4 T 3 T 5 x T 5 T 8 x x T 6 T 7 x T 8 T 7 T 6
Blocages 25 Blocage entre N processus sous 4 conditions: Les ressources considérées ne sont pas partageables Les ressources ne sont pas réquisitionnables Un ensemble de ces ressources est en attente circulaire par les processus considérés, tout en étant tenues par les même processus. Exemple : graphe d'allocation requête P1 alloué à R1 R2 alloué à P2 requête
Blocages (2) La modélisation par système de tâches est modifiée: à un événement di(l), sera associé l'allocation des ressources de l'étape l. à un événement fi(l), libération des ressources étape l, ET requête pour les ressources de l'étape l+1. Systèmes modernes plus sensibles au blocage car Programmation parallèle Système de Processus communicants Partage de ressources dynamique pour de meilleures performances. Manipulation d'objets sans avoir forcément la connaissance des verrous utilisés implicitement.... 26
Résolution du problème 27 Pour remédier au problème du blocage, trois techniques de bases Si un blocage est détecté, on met en oeuvre un mécanisme de reprise. (détection/reprise) En s'assurant qu'une des trois conditions citées cidessus n'est pas remplie. => prévention En contrôlant pas à pas l'exécution du système pour vérifier qu'on ne rentre pas dans une telle situation => évitement.
Détection reprise 28 La détection est «relativement» facile Exploration des processus et des ressources qu'ils tiennent de façon exclusive Le problème est plutôt de permettre la reprise Réquisitionner des ressources implique : Soit de tuer un processus Peut laisser le système dans un état incorrect Soit de provoquer une reprise arrière d'un processus pour qu'il libère ses ressources Généralement faisable pour les système transactionnels (Bases de données...)
Prévention 29 Basiquement, il faut supprimer une des quatre conditions : Rendre les ressources partageables Pouvoir réquisitionner les ressources Empêcher un processus de se mettre en attente avec des ressources détenues. Supprimer l'attente circulaire
Prévention 1 30 Rendre les ressources partageables Peu réaliste en réalité; certains type de ressources, comme les verrous, ne peuvent être qu'exclusif. Exemple possible : fichiers accédés en lecture. Dans certains cas particuliers, on peut améliorer la situation en augmentant le nombre d'instances d'une classe de ressource donnée. plus de mémoire...
Prévention 2 31 Pouvoir réquisitionner les ressources Difficile à réaliser : nécessite que le processus à qui on prend des ressources puisse faire «machine arrière» faisable pour la gestion de bases de données avec transactions. Certains cas simples sont implicites : réquisition de la CPU par un processus prioritaire réquisition de mémoire par déplacement d'un processus moins prioritaire sur disque.
Prévention 3 32 Empêcher un processus de se mettre en attente avec des ressources détenues. 3 solutions : Allouer TOUTES les ressources avant le début de l'exécution du processus. Fonctionne, si on peut définir la liste des ressources. très peu efficace en terme d'utilisation CPU et ressources Solution des machines mono-programmées ; fonctionnement séquentiel. N'autoriser la requête et l'attente sur une ressource que si le processus n'en détient aucune. simple si on peut l'implémenter peu réaliste Libérer toute les ressources et les ré-allouer toutes (+ la nouvelle) à chaque étape. peu réaliste dans les faits
Prévention 4 33 Supprimer l'attente circulaire introduire une relation d'ordre entre les ressources = Les allouer toujours dans le même ordre! Très efficace; utilisé par exemple dans la gestion de mémoire virtuelle de ChorusOS Ne réponds peut-être pas à tous les problèmes On veut éviter le style de programmation idiot suivant : P1 :... lock(r1)... lock(r2)... P2 :... lock(r2)... lock(r1)...
Evitement Reprenons l'exemple à deux processus et deux ressources Il y a blocage si un processus tiens une ressource et attends l'autre, et réciproquement. Représentable par un graphe d'évolution : x k+1 = x k +1 et y k+1 = y k si ak est un événement de P1 x k+1 = x k et y k+1 = y k +1 si ak est un événement de P2 34 R2 P2 Zone de blocage Zone interdite R1 Chemin A possible Chemin B possible R2 R1 P1
Evitement (2) 35 L'algorithme d'évitement doit vérifier avant chaque transition qu'on reste dans un état sûr, c.a.d qu'on ne rentre pas dans la zone interdite. Cela implique la connaissance de TOUTES les tâches de chacun des processus, en terme de demande et libération de ressources Contrainte très forte de spécification d'un système peu réalisable dans les faits. on va considérer une hypothèse plus faible qui sera suffisante bien que non nécessaire :
Algorithme du banquier 36 Chaque processus i va devoir indiquer le nombre maximum de ressources Rj détenues pour une exécution séquentielle : MAXij A chaque étape, le système va analyser l'étape suivante en supposant que TOUS les processus actifs vont arriver à cet état maximal. actif = qui tient des ressources ou en a demandé. on prend le cas le plus défavorable. Si l'état fictif maximal suivant est non bloqué, alors la requête est accordée. Sinon, la requête est rejetée, ce qui provoquera la mise en attente du processus demandeur.
Algorithme du banquier (2) 37 Avantages : fonctionne Inconvénients Consommation de CPU pour l'analyse de l'état du système! implique qu'un processus : définisse une fois pour toute sa requête maximale définisse pour chaque étape ses besoins pour l'étape suivante Fortes contraintes de programmation...
Blocages : conclusion 38 Peu d'algorithmes implémentables facilement au sein d'un système d'exploitation Les méthodes sont souvent à adapter au cas considérés : pas de méthodes génériques On trouve au sein des OS des parties de solutions de prévention pour des cas particuliers. ex :relation d'ordre dans l'allocation des ressources. Souvent, les utilisateurs, et les programmeurs, préfèrent un blocage occasionnel à des contraintes fortes de programmation/spécifications.
Synchronisation 39 On a vu qu'il était important pour un système d'être déterminé! Mais parfois, un graphe de précédence définis des contraintes trop fortes : exemple : soit la gestion d'un compte bancaire B un versement se traduit par : B = B + V un retrait par : B = B - R Versements et retraits effectués en parallèle. Dans cet exemple on a : T1 : B = B+V ; soit d1 = lecture de B et V, f1 = écriture de B T2 : B = B-R; d2 = lecture de B et R, f2 = écriture de B
Exemple de synchronisation (suite) 40 Si on laisse le système suivant s'exécuter : B=0 T 1 T 2 T' 1 T' 2 On risque d'avoir les exécutions suivantes : d1 f1 d2 f2 d'1 f'1... : correct d1 d2 f1 f2... : incorrect
Notion de section critique 41 On pourrait être tenté de définir les relations : Cela introduit une trop forte dépendance, car on n'autorise qu'un des comportements On introduit alors la notion de section critique : ensemble d'instructions (tâches) qui doivent être exécutées par un seul processus à un instant donné elles sont en exclusion mutuelle T 1 T 1 ou T 2 T 2
Section critique Pour l'étude on considérera les processus en boucle suivants : répéter <section normale> (non critique) <section critique> jusqu'à faux; La notion de section critique conduit à introduire deux nouvelles sections : répéter <section normale> (non critique) <section d'entrée> <section critique> <section de sortie> jusqu'à faux; 42
Section critique (suite) 43 Chaque processus attend dans la section d'entrée une certaines conditions, puis exécute sa section critique en exclusion mutuelle Indique sa sortie de section critique dans la section de sortie. On distinguera : des solutions logicielles et matérielles simples à ce problème, des solutions de plus haut niveau.
Solutions logicielles élémentaires 44 Variable «relais» «Drapeaux» de demande d'entrée Algorithme de Peterson Sémaphores Etudes sur cas à 2 processus; Avec plus de processus, la solution logicielle devient rapidement trop complexe.
Variable «relais» 45 Chaque processus va «donner» le relais à l'autre, et ne pourra entrer en section critique que s'il a obtenu le relais relais = une variable entière, initialement à 1. P1 P2 répéter répéter <section normale 1> <section normale 2> tant que RELAIS = 2, boucler tant que RELAIS = 1, boucler <section critique 1> <section critique 2> RELAIS = 2 RELAIS = 1 jusqu'à faux; jusqu'à faux;
Variable «relais» 46 inconvénients : impose une alternance stricte d'exécution des sections critiques attente active. Si un des processus s'arrète (en section normale), l'autre ne peux plus entrer en section critique (il le fait 1 fois en fait) condition de progression non respectée ex:mécanisme utilisé pour gérer les buffers ethernet entre le Hardware et le software...
«Drapeaux» de demande d'entrée. 47 Chaque processus signale son désir d'entrer en section critique par un «drapeau», que l'autre processus doit tester P1 P2 répéter répéter <section normale 1> <section normale 2> D1 = vrai D2 = vrai tant que D2 = vrai, boucler tant que D1 = vrai, boucler <section critique 1> <section critique 2> D1 = faux D2 = faux jusqu'à faux; jusqu'à faux; La condition de progression est cette fois vérifiée Mais risque de blocage!!! avec D1=vrai, D2=vrai simultanément => solution non acceptable.
Algorithme de Peterson Adaptation des 2 solutions précédentes pour remédier aux problèmes évoqués : L'algorithme (symétrique toujours) est : Pi (i=1 ou 2) répéter <section normale i> Di = vrai RELAIS = 3-i tant que (D 3-i = vrai et RELAIS = 3-i), boucler <section critique 1> Di = faux jusqu'à faux; Cet algorithme vérifie les propriétés : exclusion mutuelle absence de blocage progression dans tous les cas et aussi attente bornée : un processus ne peut pas exécuter plusieurs fois sa S.C au détriment de l'autre. 48
Semaphores 49 Variable de type entier Deux opérations : s.p() : prendre le sémaphore : si s 0, boucler, sinon s=s-1 s.v() : valoriser le sémaphore : s=s+1 Un sémaphore initialisé à 1 réalise facilement une exclusion mutuelle (mutex) une section critique est donc encadrée par : s.p(); <section critique> s.v(); Un sémaphore initialisé à une valeur k permet à k processus d'accéder simultanément à leur «SC»
Remarque 50 Problème des solutions abordées jusqu'à présent : l'attente active consomme la CPU Peut introduire un blocage si : un processus de basse priorité tiens un lock, un processus de haute priorité cherche à avoir le même lock => il boucle en attente active et donc empêche le processus de basse priorité de libérer le lock! => toute solution offerte par l'os devra faire appel à des files d'attentes. Le test du lock, et la mise en file d'attente doivent se faire de manière indivisible! Files d'attente de type FIFO par priorité, en général
Solutions matérielles 51 Masquage des interruptions Instructions «test and set»
Masquage des interruptions 52 Généralement au niveau processeur, pour se prémunir contre toute causes possible de préemption non sélectif : bloque l'ensemble du système ne respecte pas la priorité des processus Dangereux hors du système lui-même. Technique utilisé néanmoins au sein du système Ne fonctionne pas tel quel avec plusieurs processeurs.
Instruction matérielle spécifique 53 Appelée «test and set» ou «exchange» Atomique Principe : Ecrire une valeur dans la cellule mémoire indiquée (1 pour TAS), et retourner la valeur stockée précédemment dans le registre : ex intel : XCHG (%reg), %eax on ecrit 1, et on verifie ensuite s'il y avait deja 1 en mémoire : si oui, le lock était déjà pris => on doit re-boucler si non, on a le lock. C'est un mutex simple. Cette instruction est en général utilisée pour implémenter des mutex au sein de l'os.
Solutions de plus haut niveau 54 Les solutions précédentes ont l'inconvénients de reposer sur le bon vouloir et les capacités du programmeur risque de blocage si erreur de conception ou risque de corruption des sections critiques qu'on veut protéger On introduit donc de nouveaux mécanismes, offerts par les langages de programmations : Moniteurs «Sérialiseurs» Expression de séquence d'opérations («path expression»)...
Moniteur 55 Structure regroupant des ressources à partager, et les opérations permettant d'y accéder Un seul processus peut être actif au sein d'un moniteur exclusion mutuelle implicite Exemple : le compte en banque : Moniteur : compte var N : entier début : N = 0; fin; procédure depot(v) { N = N+V; } procédure retrait (V) { N = N -V; } Un retrait : compte.retrait(v); Un dépôt : compte.depot(v);
Moniteur (suite) 56 Typiquement en Java : les objets «synchronized» Faiblesse des moniteurs : Accès en un seul «bloc», pas de finesse de synchronisation Inadapté par exemple au cas des «lecteurs/écrivains» on introduit la notion de variable «condition», qui sont en fait des files d'attentes liés au moniteur, et qui permettent de libérer, temporairement l'accès exclusif, au sein d'une procédure. X : condition X.wait(), X.signal() les 2 méthodes Voir exemple (TD) des lecteurs/écrivains en Java : wait(), notify();