Vous êtes sur la page 1sur 5

1.2.

b La commutation de contexte

La commutation (ou changement) de contexte est l’opération qui, d’une part, sauvegarde le contexte
du processus à qui on retire le processeur et qui, d’autre part, rétablit le contexte du processus qui vient
d’être choisi pour bénéficier du processeur (figure 1.3.b). La commutation de contexte assure à un processus
qu’il retrouvera toutes les informations dont il a besoin pour reprendre l’exécution de son programme là où il
a été interrompu. Les commutations de contexte arrivent très souvent : après chaque quantum de temps,
chaque fois que le noyau du système d’exploitation prend la main et chaque fois qu’un processus est dessaisi
du processeur avant la fin du quantum qui lui était attribué (parce qu’il attend une entrée/sortie, par
exemple). L’opération de commutation de contexte doit donc être très rapide et, en pratique, elle est souvent
assurée en grande partie par les couches matérielles de la machine. Les machines les plus performantes
effectuent un changement de contexte en quelques microsecondes et cette opération influe donc peu sur les
quantums attribués aux processus (qui, eux, sont de l’ordre de la dizaine de millisecondes).

1.3 Les Threads ou processus léger

Le modèle de processus décrit précédemment est un programme qui s'exécute selon un chemin
unique avec un seul compteur ordinal. On dit qu'il a un flot de contrôle unique ou un seul thread. De
nombreux systèmes d'exploitation modernes offrent la possibilité d'associer à un même processus plusieurs
chemins d'exécution ou multithread (figure1.5). Ils permettent ainsi l'exécution simultanée des parties d'un
même processus. Chaque partie correspond à un chemin d'exécution du processus. Le processus est vu
comme étant un ensemble de ressources (code exécutable, segments de données, de fichiers, de
périphériques, etc.) que ces parties appelées flots de contrôle ou processus légers (threads en anglais)
partagent. Chaque flot de contrôle (thread) a cependant, en plus des ressources communes, sa propre zone de
données ou de variables locales, sa propre pile d'exécution, ses propres registres et son propre compteur
ordinal.
Comparativement aux processus à un flot de contrôle unique, un thread ou processus léger avec plusieurs
flots de contrôle présente plusieurs avantages, notamment :
• Réactivité : Le processus léger continue à s'exécuter même si certaines de ses parties sont bloquées.
• Partage de ressources.
• Économie d'espace mémoire et de temps : Par exemple sous Solaris, la création d'un processus est
30 fois plus lente que celle d'un processus thread.

Figure 1.5 : Processus à un thread et à plusieurs threads


La majorité des systèmes permettent le multi-flot (multithreading). Ils sont offerts soit au niveau
utilisateur, soit au niveau noyau. Les threads utilisateur sont supportés au-dessus du noyau et sont
implantés par une bibliothèque de threads au niveau utilisateur (par exemple pthread sous Linux ou thread
dans Solaris). Ils sont portables sur différentes plate-formes. Ils sont gérés par une application où le blocage
du thread peut bloquer le processus complet. Le changement de contexte est rapide. Les threads noyau sont
directement supportés par le noyau du système d'exploitation. Le système d'exploitation se charge de leur
gestion et le changement de contexte est lent. Les threads combinés sont implantés par le système
d'exploitation (utilisateur et système). Les threads utilisateur sont associés à des threads système. Les
opérations concernant les threads sont notamment la création, la terminaison, la suspension et la relance.

1.4 Gestion de ressources

Pour qu’un processus puisse s’exécuter, il a besoin de procédures et de données, de mémoire destinée
à les contenir, de l’unité centrale, éventuellement de fichiers et de périphériques. Nous appelons toutes ces
entités des ressources. Etant une entité nécessaire à l’exécution d’un processus, une ressource peut être
matérielle (unité centrale, mémoire centrale, périphériques,…) ou logicielle (variable partagée, fichier,…). Il
faut noter qu’à chaque type de ressource est associé dans le système une procédure d’allocation et qu’à
chaque ressource correspond un descripteur. Le descripteur minimal se réduit à un bit représentant l’état
libre ou alloué de la ressource.

Pour chaque ressource, une caractéristique importante est le nombre de processus qui peuvent utiliser
la ressource au même moment (c’est-à-dire le nombre de points d'accès) :
- Il peut y avoir un nombre quelconque : Il n'y a alors pas de contrôle à mettre en œuvre.
- Il peut y en avoir plusieurs, mais en nombre limité : Il faut alors contrôler lors des allocations que ce
nombre n'est pas dépassé.
- Il peut y avoir au plus un processus qui utilise la ressource : On dit alors que la ressource est une ressource
critique ; On dit aussi que les processus sont en exclusion mutuelle pour l'accès à cette ressource.

Pour des raisons économiques, les ressources sont dans la majorité des cas, en quantité insuffisante
pour répondre aux demandes de pointes. Ils se forment donc des files d’attente de processus demandeurs de
ressources. Le mécanisme général est le suivant : Une demande de ressource est adressée au système
d’exploitation par un processus, si la ressource n’est pas disponible, il y a blocage et mise en file d’attente du
processus demandeur, sinon l’allocation de la ressource a lieu et le processus demandeur poursuit son
déroulement. Le système d’exploitation reçoit aussi des demandes de restitution de ressources. Le
mécanisme est alors le suivant : La ressource libérée est remise dans l’ensemble des ressources disponibles,
si des processus sont en attente sur la disponibilité de cette ressource, un ou plusieurs d’entre eux seront
débloqués. Il est important de distinguer le programme système (l’ordonnanceur) de sélection du prochain
processus à activer du programme système (le dispatcher, distributeur ou commutateur) qui provoque la
réactivation du processus choisi.

Il est aussi nécessaire d’étudier l’allocation des ressources sous deux aspects : les mécanismes et les
politiques. Les mécanismes sont les moyens mis en œuvre pour réaliser l’allocation des ressources
(structures de données pour décrire les ressources, les techniques pour assurer l’usage exclusif des ressources
critiques, les files d’attente des requêtes qui ne peuvent être servies immédiatement,…). Les politiques
gouvernent la façon d’utiliser les mécanismes pour garantir le service des requêtes. Une allocation mal
avisée peut entraîner une surcharge du système sur une classe particulière de ressources ou une impossibilité
d’exploitation des processus.

Ressource requérable : une ressource est sujette à réquisition (préemption) si le système


d’exploitation peut la retirer à un processus alors que celui-ci en a encore besoin. Par exemple le processeur
(la sauvegarde du PCB du processus interrompu et la restauration de celui qui est élu : la commutation de
contexte) ; par contre l’imprimante est une ressource non requérable (elle ne peut pas être réquisitionnée).
Pour chaque type de ressources il existe généralement divers algorithmes. Il est difficile de définir le
meilleur, car dans l’évaluation de leurs qualités interviennent des facteurs opposés tel que l’utilisation
optimale et le coût de l’algorithme.

1.5 Programmation parallele et concurrence

1.5.1 Qu’est-ce que la programmation concurrente

Il s’agit d’un anglicisme : il ne faut pas comprendre « concurrence » au sens traditionnel du mot, qui
suggère la notion de compétition; il faut comprendre plutôt concurrency, qui suggère la notion de
simultanéité ou de concourance, l’idée que plusieurs actions ou événements se déroulent au même
moment. Nous parlerons de concurrence lorsque plusieurs processus s’exécutent de façon simultanée. Au
sein de chaque processus, l’exécution est séquentielle, c’est-à-dire que les instructions sont exécutées les
unes après l’autre, dans l’ordre dicté par le programme. Cette définition est (intentionnellement) très
générale et peut recouvrir déférentes situations particulières. En particulier, la notion de simultanéité peut
être comprise de déférentes manières. Il peut par exemple y avoir partage du temps (time-sharing ) entre
déférents processus exécutés par un unique processeur. Il peut y avoir, au contraire, exécution de chaque
processus par un processeur distinct. Enfin, il peut y avoir combinaison de ces deux idées : on peut imaginer
n processus exécutés par p processeurs, avec n > 1 et p > 1. On parle de parallélisme lorsque plusieurs
processeurs (ou plusieurs cœurs d’un même processeur, ce qui pour nous revient au même) sont utilisés.

Lorsque l’on souhaite diviser un travail complexe en un certain nombre de tâches, afin que chacune
de ces tâches puisse être exécutée par un processus distinct, on est immédiatement confronté à la nécessité
d’autoriser communication et synchronisation entre processus. En effet, déférents processus doivent
pouvoir communiquer, c’est-à-dire échanger des données : par exemple, chaque processus doit recevoir
initialement une description de sa tâche, et doit une fois cette tâche terminée transmettre une description du
résultat. De plus, déférents processus doivent pouvoir se synchroniser, c’est-à-dire attendre : par exemple, un
processus qui souhaite exploiter le résultat d’une tâche doit pouvoir attendre que ce résultat soit produit par
le processus à qui cette tâche a été attribuée.

Communication et synchronisation peuvent être réalisées de déférentes façons. La communication


entre deux processus peut se faire de façon implicite, par exemple à travers une mémoire partagée, ou bien
de façon explicite, par exemple par échange de messages à travers un canal partagé. La synchronisation
entre processus est parfois implicite et gérée par la machine.

1.5.2 Modèles de représentation d'un système de tâches

Il existe plusieurs représentations graphiques permettant la description et l'analyse d'un système de


tâches: le graphe de précédence, les automates finis et les réseaux de Pétri.

1.5.2.a Graphes de précédence


Les graphes de précédence permettent de représenter les relations de précédence d'un système de
tâches. Une relation de précédence sur un ensemble E est une relation vérifiant les propriétés suivantes:
1) pour tout T de l'ensemble E, T < T est impossible
2) pour tout (T1, T2) de E x E, T1 < T2 et T2 < T1 est impossible simultanément
3) la relation < est transitive
Il s’agit d’un graphe orienté acyclique (figure 1.6) dont les nœuds représentent les tâches (ou
processus) et les arcs représentent les dépendances entre les nœuds incidents : un arc d’un nœud Ti vers un
nœud Tj signifie que le nœud Tj ne peut s’exécuter avant la fin du nœud Ti.
Figure 1.6 : Un graphe de précédence et son implémentation à l’aide de Fork/Join

Un système de tâches (E, <) est un ensemble E de tâches muni d'une relation de précédence <. Un
système de tâches peut se représenter sous forme de graphe orienté. Les sommets sont les tâches et les arcs
représentent les relations de précédence entre les tâches. Un arc de la tâche Ti vers la tâche Tj existe si et
seulement si Ti < Tj.
On introduit deux lois de composition S(a,b) et P(a,b) où a et b désignent des processus, telle que :
S(a,b) représente l’exécution en série des processus a et b, alors que P(a,b) représente leur exécution en
parallèle (figure 1.7).

Figure 1.7 : Graphes de précédence de S(a,b) et P(a,b).


Exercice 1.1 :
En utilisant les seules fonctions S et P, donner, lorsque c’est possible, une description des graphes de
précédences de la figure 1.8.

Figure 1.7 : Des exemples de graphes de précédences


Exercice 1.2 :
Soit l’expression : (a+b)*(c+d)-(e/f)
1)- Donner la structure d’arbre correspondante
2)- Donner un graphe de précédence correspondant à une évaluation parallèle de cette expression. On
cherchera à exploiter au mieux le parallélisme.
3)- Donner une description de ce graphe en utilisant les seuls fonctions S et P.

1.5.2.b Spécification dans les langages évolués


Il s'agit de représenter à travers un langage la mise en séquence ou en parallèle des tâches d'un graphe de
précédence.
1)- Fork/Join
L’instruction Fork L produit deux activités parallèles à partir du programme : l’une commence à
l’instruction étiquetée par L et l’autre est la continuation de l’exécution après l’instruction Fork.
Exemple :
I1 ;
Fork L ;
I2 ;

L: I3;

L’instruction Join n permet de joindre (combiner) n activités parallèles en une seule activité. Les (n-
1) premières activités qui exécutent l’instruction join n se terminent, tandis que la nième activité continue en
séquence. L’exécution de l’instruction Join n est équivalent à :
n=n-1 ;
Si n≠0 alors terminer.

2)- Bloc d’instructions parallèles


Les deux instructions CoBegin et CoEnd (ou ParBegin et ParEnd) permettent de délimiter un bloc
d’instructions parallèles. La syntaxe d’utilisation est : CoBegin i1 ;i2 ;….. ;in CoEnd
Les instructions Ij (j=1 . . . n) peuvent s’exécuter en parallèle (figure 1.8).

Figure 1.8 : Un exemple d’utilisation de CoBegin/CoEnd.


1.6 Les processus sous Unix

Vous aimerez peut-être aussi