Вы находитесь на странице: 1из 63

SUPPORT DE COURS

SYSTEMES D’EXPLOITATION I
L 2ième Systèmes d’Information et BDD

Préparé par Mr. Mokaddem. M (Enseignant à l’Université d’Oran)


Modifié et complété par Mr. Kadri .W (Enseignant à l’Université de Chlef)
Avec l’autorisation de l’auteur

Année Universitaire : 2013 / 2014

© W. KADRI 1
INTRODUCTION GENERALE

Arrivés presque à terme de l'enseignement classique, nous nous sommes rendus


compte que nombreux étaient les étudiants qui n'avaient aucune visibilité sur la
conception d'un système d’exploitation. La définition d'un OS étant très floue et
compliquée nous avons voulu montrer, à travers ce cours, qu'il est possible de
démystifier ce concept et de le rendre très clair.

En effet, le but du cours est de présenter les principes de fonctionnement des


systèmes d'exploitation afin que l’étudiant puisse maîtriser la structure et le
fonctionnement interne des OS. Une telle compréhension en profondeur n'est pas
simplement pédagogique: elle permet d'avoir une vision synthétique du
fonctionnement de tout le système. Elle permet de mieux interpréter les
comportements étranges, de mieux cibler les causes potentielles des erreurs qu'on est
amené à rencontrer en travaillant sur la plupart des systèmes. Nos espérances
seraient que cet ouvrage puisse, d’un côté, guider les professeurs et les formateurs
dans l’enseignement des systèmes d’exploitation, grâce à des exercices corrigés
venant renforcer ses qualités didactiques et d’un autre être lu avec profit par des
étudiants en informatique qui y trouveront un matériel précieux illustrant par des
cas réels les concepts étudiés en cours.

Cet ouvrage est le fruit d’une expérience personnelle des auteurs qui ont enseignés ce
module pendant très longtemps (au minimum dix ans d’affilés). Les concepts ainsi
que la bibliographie sont une synthèse très riche réalisée, essentiellement, à partir
des livres, dans leurs différentes versions, de A. Tenanbaum, A. Silberchartz, W.
Stallings. A travers une rédaction simple et pédagogique, cet ouvrage présente les
concepts fondamentaux de tout système d’exploitation en cinq chapitres dont chacun
est complété par une batterie d’exercices aussi riches que variés afin de cerner tout
les aspects des concepts présentés dans le chapitre respectif. Le chapitre premier
présente des généralités sur les systèmes d’exploitation, les situe dans l’architecture
de la machine à travers le temps et l’espace et montre comment ils sont structurés. Le
chapitre deuxième présente la translation d’un programme d’un code source vers son
code machine et montre comment se fait la naissance d’un processus qui représente
l’acteur principal de tout OS. Le chapitre troisième s’occupe de la gestion des
processus et montre la définition d’un processus, son scheduling, sa synchronisation,
sa communication et sa concurrence avec d’autres processus, une vue de
l’implémentation de cette gestion devient plus explicite grâce aux structures de
données et les algorithmes présentés dans ce chapitre. Le quatrième chapitre montre
la notion de multiprogrammation, de swapping et de mémoire virtuelle,, on y
retrouve les systèmes de gestion de la mémoire du plus simple au plus compliqués,
les algorithmes selon chaque classe de systèmes sont explicités, il se clôture par les
différents concepts de conception de systèmes à mémoire virtuelle. Le chapitre
quatrième se consacre à la gestion des périphériques et des entrées sorties et montre
le cheminement d’une entrée/sortie à travers ses différentes phase, la notion de
scheduling du bras, de pilote, de primitives systèmes d’entrée/sortie montre cette
mise en œuvre, l’allocation et la libération de ressources nécessitent une bonne
© W. KADRI 2
gestion afin d’éviter les interblocages. Enfin le dernier chapitre relève de la gestion de
fichiers, on y trouve les concepts de fichiers, de répertoire, d’arborescence,
l’allocation et la désallocation d’espace aux fichiers et répertoires, FAT32, NTFS et les
inodes d’Unix sont le point forts de la compréhension des systèmes de fichiers.
Arrivés au terme de ces chapitres, nous espérons que le lecteur ait développé une
vision assez réaliste des fonctionnalités disponibles sur un système quelconque, et de
pouvoir reconduire les différents aspects étudiés vers ses propres fins. Une bonne
maitrise de l'architecture et des mécanismes impliqués, conduit à une bonne
programmation système avec une manipulation prometteuse et efficace de ces
concepts.

© W. KADRI 3
Premier Chapitre
GENERALITES

1- INTRODUCTION

Dans les premiers âges de l’informatique, les programmeurs chargeaient directement


leurs programmes en mémoire via des pupitres dédiés, indiquèrent, manuellement,
une adresse début et, enfin, ordonnèrent le processeur de s’y brancher. Ceci
nécessitait une connaissance approfondie de la machine et une très bonne maitrise de
la part des programmeurs ce qui ralentissait énormément le développement
informatique. Fort heureusement, que quelques années plus tard sont apparus Les
systèmes d'exploitation (noté SE ou OS, abréviation du terme anglais Operating
System), pour promouvoir le succès des ordinateurs, des deux dernières décennies,
en permettant aux programmeurs de s'affranchir de la complexité de la machine
physique.

Un système d’exploitation est un ensemble de programmes softwares offrant un


environnement de programmation dans lequel d’autres programmes peuvent
s’exécuter et prendre avantage du processeur et de ses organes d’entrée/sortie. De
cette manière, ils assurent la liaison entre les ressources de la machine, l'utilisateur et
les applications (traitement de texte, jeu vidéo, ...). Ils permettent, ainsi, de "dissocier"
les programmes et le matériel, afin notamment de simplifier la gestion des ressources
et d’offrir à l'utilisateur une interface homme-machine virtuelle.

Plus précisément, les systèmes d’exploitation offrent deux services fondamentaux


aux utilisateurs : le premier permet un usage facile du hardware, en définissant et
créant une machine virtuelle qui diffère de marque, uniquement, de la machine réelle.
Le deuxième permet de gérer les ressources, par partage, entre plusieurs utilisateurs.
Une des plus importantes ressources est le processeur.

En plus du partage du processeur, le système gère la mémoire et régularise l’accès aux


fichiers et organes d’entrée/sortie. Les systèmes se distinguent les uns des autres selon la
façon dont ils présentent leurs machines virtuelles et leur gestion des ressources.

2- ROLES DU SYSTEME D'EXPLOITATION

Les rôles du système d'exploitation sont divers :

 Gestion du processeur : le système d'exploitation est chargé de gérer


l'allocation du processeur entre les différents programmes grâce à un
algorithme d'ordonnancement. Le type d'ordonnanceur est totalement
dépendant du système d'exploitation, en fonction de l'objectif visé.

© W. KADRI 4
 Gestion de la mémoire vive : le système d'exploitation est chargé de gérer
l'espace mémoire alloué à chaque application et programme. En cas
d'insuffisance de mémoire physique, le système d'exploitation peut créer une
zone mémoire sur le disque dur, appelée «mémoire virtuelle». La mémoire
virtuelle permet de faire fonctionner des applications nécessitant plus de
mémoire qu'il n'y a de mémoire vive disponible sur le système. En
contrepartie cette mémoire est beaucoup plus lente.
 Gestion des entrées/sorties : le système d'exploitation permet d'unifier et de
contrôler l'accès des programmes aux ressources matérielles par
l'intermédiaire des pilotes (appelés également gestionnaires de périphériques
ou gestionnaires d'entrée/sortie).
 Gestion de l'exécution des applications : le système d'exploitation est chargé
de la bonne exécution des applications en leur affectant les ressources
nécessaires à leur bon fonctionnement. Il permet à ce titre de «tuer» une
application ne répondant plus correctement.
 Gestion des droits : le système d'exploitation est chargé de la sécurité liée à
l'exécution des programmes en garantissant que les ressources ne sont
utilisées que par les programmes et utilisateurs possédant les droits adéquats.
 Gestion des fichiers : le système d'exploitation gère la lecture et l'écriture
dans le système de fichiers et les droits d'accès aux fichiers par les utilisateurs
et les applications.
 Gestion des informations : le système d'exploitation fournit un certain
nombre d'indicateurs permettant de diagnostiquer le bon fonctionnement de
la machine.

3- COMPOSANTES DU SYSTEME D'EXPLOITATION

Le système d'exploitation est composé d'un ensemble de logiciels permettant de


gérer les interactions avec le matériel. Parmi cet ensemble de logiciels on distingue
généralement les éléments suivants :

 Le noyau (en anglais Kernel) représentant les fonctions fondamentales du


système d'exploitation telles que la gestion de la mémoire, des processus, des
fichiers, des entrées-sorties principales, et des fonctionnalités de
communication.
 L'interpréteur de commande (en anglais Shell, traduisez «coquille» par
opposition au noyau) permettant la communication avec le système
d'exploitation par l'intermédiaire d'un langage de commandes, afin de
permettre à l'utilisateur de piloter les périphériques en ignorant tout des
caractéristiques du matériel qu'il utilise, de la gestion des adresses physiques,
etc.
 Le système de fichiers (en anglais File System, noté FS), permettant
d'enregistrer les fichiers dans une arborescence.

© W. KADRI 5
4- DECOMPOSITION HIERARCHIQUE DE LA MACHINE

Pour mieux comprendre le fonctionnement des systèmes d’exploitation, il faudrait


d’abords comprendre comment est structuré le matériel pour le quel ils ont été
conçus.

D’une manière générale, le matériel est décomposé d’une machine nue et d’une
machine abstraite :
- Une machine nue est définie par :
 Un répertoire de base ou l’ensemble des instructions machines ou
primitives
 Une mémoire composée des registres du processeur et de la mémoire
principale
 Un mécanisme d’exécution représentant le cycle ou la méthode
d’exécution d’une instruction (lecture, décodage et exécution de
l’instruction)

- Une machine abstraite est définie par tout langage capable de l’interpréter. Elle est
dite abstraite parce qu’elle n’a pas de représentation physique. Par sa définition
générale, le langage permet de définir :
 Des objets et les mécanismes permettant de les créer.
 Des actions (primitives) permettant de manipuler ces objets.
 Des règles de composition de ces actions.

De là on peut définir une machine abstraite comme étant :


 Un répertoire de base qui est l’ensemble des primitives du langage
 Une mémoire qui est la représentation des objets par ce langage
 Un mécanisme d’exécution qui est l’ensemble des règles
d’interprétation du langage

Si on appelle M la machine nue, on peut définir une machine M0 en associant un


langage à M tel que la spécification de M0 se réduit, uniquement, à son interface,
donc aux objets et règles offerts par M0. Ainsi, une machine Mi ne dépend que de Mj
et non des détails de sa réalisation interne. La relation entre machine est dite relation
de dépendance

Ainsi, la structure d’un système est une décomposition hiérarchique de plusieurs


machines décrivant un graphe. Cette décomposition hiérarchique en niveau présente
plusieurs avantages qui résultent de l’indépendance introduite par l’abstraction :

 Indépendance de conception : chaque machine est décrite par son interface.


 Indépendance de modification : la modification d’une machine n’implique
aucune modification des machines qui l’utilisent tant que l’interface reste
inchangée.
 Indépendance de mise au point : une fois son interface spécifiée, une
machine peut être mise au point indépendamment des machines qui
l’utilisent et inversement. D’où la notion de portabilité.

© W. KADRI 6
Un système constitue, donc, une interface entre l’utilisateur et la machine qui se
définit par un langage ou un moyen de communication. Toute information,
nécessaire à la bonne gestion du système, doit être contenue dans cette interface. Une
tâche exprimée très simplement selon les avantages offerts par la machine abstraite
s’avère plus complexe à un niveau d’abstraction inférieur. Donc une opération de
haut niveau se décompose en plusieurs opérations de bas niveau.

D’autre part, plusieurs machines virtuelles (abstraites) peuvent être définies sur une
même machine pour des utilisateurs différents. De là, il apparaît la décomposition
suivante figure1.2 :

USER USER USER .. .. .. USER


1 2 3 n

Logiciel d’application

Compilateur Assembleur Editeur de texte. . . Base de données

Système d’exploitation

Logiciel de Base

Machine Physique

Figure1.2 : Situation abstraite d’un système d’exploitation

 Un utilisateur est caractérisé par un logiciel d’application qui constitue son


environnement de travail. Tout utilisateur a son propre environnement.
 Une partie commune à tous les utilisateurs appelée logiciel de base. Tout
logiciel d’application dépend de cette partie.

Les frontières entre ces couches ne sont pas définitives, il arrive parfois qu’un logiciel
d’application puisse être intégré au logiciel de base. Ce qui est la tâche du manager.
Une fonction du logiciel de base peut être câblée par besoin d’économie. Ce qui est la
tâche du concepteur.

A l’intérieur du logiciel de base, nous distinguons les outils et services


(compilateurs, éditeurs, utilitaires…) ainsi que le système d’exploitation lui-même.

5. HISTORIQUE DES SYSTEMES D’EXPLOITATION


Pour comprendre encore mieux les systèmes d’exploitation et ce qu’ils font, il
faudrait voir comment ils se sont développés au cours de cette dernière décennie. En
suivant cette évolution, on pourra identifier les éléments communs à ces systèmes et
comprendre leur développement.

© W. KADRI 7
Comme les systèmes d’exploitation dépendent étroitement de l’architecture des
ordinateurs sur lesquels ils fonctionnent, on passera en revue les générations
d’ordinateurs pour en examiner les différents systèmes d’exploitation.

5.1 Première génération (1945-1955)


Les machines étaient construites au moyen de tubes électroniques. Il y eu
l’introduction de cartes perforées et la naissance de quelques logiciels de base qui
furent les outils de développements de programmes (assembleurs, compilateurs, aide
à la mise au point) et des sous programmes d’E/S. Ce modèle s’appelle la porte
ouverte open Shop
 Inconvénients : peu économique par rapport au prix du matériel, mauvaise
gestion du matériel.

5.2 Deuxième génération (1955-1965)


La naissance des transistors améliorait la situation où les ordinateurs devinrent
suffisamment fiables pour être construits et vendus. Pour lancer un job, le
programmeur écrit et tape son programme sur des cartes perforées et les remet à
l’opérateur qui prépare le compilateur en question, lance l’exécution et remet les
résultats de l’imprimante au programmeur qui corrige son programme et ainsi de
suite. La majeure partie du temps de l’ordinateur est perdue au cours des
déplacements de l’opérateur. On adopta, alors, le traitement par lots Batch
Processing qui consiste à rassembler un ensemble de travaux et préparer leur
exécution, d’où la naissance des moniteurs d’enchaînement qui consistaient à
automatiser le passage d’un programme à un autre.

 Inconvénients : Les E/S étaient gérées par le CPU d’où la faiblesse du


rendement.

La solution à ce problème était la naissance du parallélisme entre le traitement et les


E/S. Une première solution consiste à utiliser deux ordinateurs séparés, un pour le
traitement et l’autre pour les E/S (IBM 1401 pour les E/S et IBM 7094 pour le
traitement).
 Inconvénients : déplacement des bandes coûteux en temps.

La deuxième solution est l’intégration des canaux d’E/S. Un canal ou unité


d’échange est un processeur capable d’exécuter des E/S de manière autonome,
indépendamment du processeur central qui exécute le traitement proprement dit.

 Inconvénients : Le CPU et les canaux accèdent à des informations communes


en mémoire centrale, et les vitesses, relatives au traitement et au transfert,
deviennent un facteur important. Le débit du périphérique est très faible
par rapport à la capacité de traitement.

En voulant faire du transfert simultané, on a crée une accumulation d’information


sous forme de buffers d’E/S en MC. La solution est de transporter les buffers en
mémoire secondaire à grande capacité telle que le débit de transfert soit un peu plus
élevé que les périphériques lents. Ces transferts sont généralement commandés par
un canal.
© W. KADRI 8
Cette forme de traitement est appelée SPOOLING figure1.3 (Simultaneous Peripheral
Operation On Line. Le Spooling) utilise essentiellement le disque comme un buffer
très grand pour lire sur les dispositifs d’entrées et mémoriser les fichiers de sortie
jusqu’à ce que les dispositifs de sorties puissent les accepter.

C
CPPU
U

LECTEUR
CANAL
M
MCC CANAL PRINTER

CANAL

DISQUE

Figure1.3 : Le Spooling

Inconvénients : le processeur reste inactif pendant la durée de l’E/S. Un travail bref


arrivant pendant l’exécution d’un travail lent attend la fin de celui-ci.

La solution est qu’il faut songer à un système qui accepte plusieurs programmes en
mémoire centrale.

5.3 Troisième génération (1965-1980)

Cette génération est caractérisée par la naissance des circuits intégrés et la


multiprogrammation. Des mémoires rapides et de grande capacité ont vu le jour et
ont permis de penser au partage de celles-ci entre plusieurs utilisateurs en même
temps.

On dit qu’il y a multiprogrammation lorsque plusieurs programmes coexistent en


mémoire et que le déroulement de l’un peut être interrompu au profit d’un autre
avec reprise ultérieure du programme interrompu.

La solution qui en résulte consiste à partitionner la mémoire. Chaque partition


contient une tâche différente. Lorsqu’une tâche attend la fin d’une E/S, une autre
tâche peut utiliser le CPU.

© W. KADRI 9
 Inconvénients :

a- Complexité du système : partage de la mémoire et protection des


programmes entre eux en mémoires centrale et secondaire.
b- Partage des ressources : équilibre de la charge du CPU, mémoire centrale et
des organes d’E/S.
c- Protection mémoire et réentrance.

La solution est donc la naissance du temps partagé dont le principe consiste à allouer
à chaque utilisateur une portion de temps (quantum) lui permettant de disposer de
toutes les ressources dont il a besoin.

Cette génération fut aussi caractérisée par le développement des systèmes temps réel
qui sont une forme de systèmes d’exploitation spécialisés. Ils consistent à conduire
des processus industriels par un ordinateur fonctionnant dans un environnement
contraint temporellement. L’ordinateur fait lui-même des prélèvements de données
dont il a besoin (température, pression, etc.…) et agit directement sur les organes du
processus industriel. L’ordinateur veille à ce que les mesures prises soient normales
et ne dépassent pas un certain seuil. Sinon, il provoque l’arrêt du processus
industriel. Un système temps réel doit ainsi fonctionner de manière fiable selon des
contraintes temporelles spécifiques, c'est-à-dire qu'il doit être capable de délivrer un
traitement correct des informations reçues à des intervalles de temps bien définis
(réguliers ou non).

5.4. Quatrième génération (1980 – 1990)

Cette génération est caractérisée par les ordinateurs personnels, les réseaux et les
systèmes répartis.

 Ordinateurs Personnels

Les PCs sont apparus dans les années 1970 grâce à l’électronique LSI (Large Scale
Integration) et VLSI. Leurs systèmes d’exploitation tels que CPM, MSDOS, OS/2,
Xenix et Unix étaient ni multi-utilisateurs ni multi-tâches ils optaient surtout pour la
commodité et la rapidité.
En même temps, du matériel puissant, rapide et sophistiqué a vu le jour : Les
stations de travail comme les stations Sun, Appolo d’HP ou la RS/6000 d’IBM sont
des résultats d’un grand effort.

 Les systèmes distribués

De tels systèmes possèdent plus d’un processeur en étroite communication


partageant le bus de l’ordinateur, l’horloge et quelquefois la mémoire et les
périphériques. Il existe plusieurs raisons pour créer de tels systèmes :
- En augmentant le nombre de processeurs, on espère améliorer la capacité de
traitement, c’est à dire, effectuer plus de travail en moins de temps.

© W. KADRI 10
- La fiabilité. Si l’on peut distribuer correctement les fonctions parmi les
différents processeurs, une panne d’un processeur n’arrêtera pas le système
mais peut être le ralentira seulement. Les autres processeurs auront à effectuer
les tâches du processeur en panne jusqu’à son rétablissement. Ce mode de
fonctionnement s’appelle le mode dégradé.

Les systèmes multiprocesseurs actuels les plus courants utilisent le modèle de


traitement symétrique où chaque processeur exécute une copie du système
d’exploitation. Au besoin, ces copies communiquent entre elles. D’autres utilisent le
traitement asymétrique où à chaque processeur est assignée une tâche spécifique. Un
processeur maître contrôle le système, les autres attendent que le maître donne des
instructions. Le processeur maître alloue par scheduling du travail aux processeurs
esclaves. Dans de tels systèmes, les utilisateurs n’ont pas à connaître où se trouvent
leurs fichiers ou leurs programmes. Les systèmes distribués permettent l’exécution
simultanée et distribuée de plusieurs programmes sur plusieurs processeurs. Le
scheduling est complexe et doit optimiser le parallélisme. Il doit également se
dérouler en cas d’informations incomplètes ou fausses à cause des délais de
communication.

 les systèmes répartis

Les processeurs ne partagent pas de mémoire ni d’horloge. Au lieu de cela, chaque


processeur possède sa propre mémoire locale. Les processeurs communiquent à
travers diverses lignes de communication.

Dans un système réparti, les processeurs peuvent varier en taille et en fonction. Ils
peuvent inclure des PCs, des stations, des mini-ordinateurs et de grands systèmes à
usage général. Ces processeurs portent différentes appellations sites, nœuds,
ordinateurs, etc. Dans un tel système, les utilisateurs connaissent l’existence des
différents sites, peuvent se connecter sur une machine distante et transférer des
fichiers d’une machine à une autre. Chaque ordinateur fonctionne avec son propre
système et au compte d’un utilisateur particulier.

Les raisons pour construire des systèmes répartis sont le partage des ressources,
l’accélération du calcul, la fiabilité et la communication.

 Les systèmes embarqués

Les systèmes embarqués sont des systèmes d'exploitation prévus pour fonctionner
sur des machines de petite taille, telles que des PDA (personal digital assistants ou en
français assistants numériques personnels) ou des appareils électroniques autonomes
(sondes spatiales, robot, ordinateur de bord de véhicule, etc.), possédant une
autonomie réduite. Ainsi, une caractéristique essentielle des systèmes embarqués est
leur gestion avancée de l'énergie et leur capacité à fonctionner avec des ressources
limitées.

© W. KADRI 11
Les principaux systèmes embarqués «grand public» pour assistants numériques
personnels sont :
 PalmOS
 Windows CE / Windows Mobile / Window Smartphone

6. STRUCTURE DES SYSTEMES D’EXPLOITATION

Un système doit être conçu soigneusement pour fonctionner correctement et être


modifié facilement.

6.1 Système monolithique

Le système est, dans ce cas, un ensemble de procédures pouvant s’appeler entre elles.
Chaque procédure doit avoir une interface bien définie. Le système est considéré
comme une seule pièce, lorsqu’il prend le contrôle il masque toutes les
caractéristiques matérielles en particulier les interruptions.
 Avantage : Cette structure est relativement simple à concevoir et à
implémenter.
 Inconvénient : n’importe quelle interruption invoque le système et masque
toutes les autres. Ce qui tend à dégrader le temps de réponse, spécialement
quand il y a plusieurs processus.

MSDOS en est un exemple écrit pour fournir le plus de fonctionnalité possible dans
le moindre espace, à cause du matériel sur lequel il allait tourner. Les programmes
d’application sont capables d’accéder aux routines D’E/S de base (BIOS) afin d’écrire
directement sur l’écran ou sur l’unité de disque par exemple. Un tel risque rend
MSDOS vulnérable devant les programmes erronés, ce qui se caractérise par des
blocages complets assez souvent du système.

Figure1.4 : La structure de MSDOS

6.2 Système en couches

Dans l’approche en couches, on dit également noyau, le système est réparti en un


noyau et un nombre de processus systèmes s’exécutant simultanément. Chaque

© W. KADRI 12
couche représente une machine virtuelle cachant tous les détails de la machine de
niveau inférieur.

 Avantage : est la modularité. Les couches sont sélectionnées de telle sorte que
chacune utilise seulement les fonctions et services des couches inférieures.
Cette approche simplifie la mise au point du système.

 Inconvénient : pour exécuter une opération d’E/S, un programme utilisateur


doit exécuter un appel système à la couche gestion des E/S qui appelle, elle-
même, la couche gestion de la mémoire puis la couche scheduling du CPU et
enfin le matériel. Dans chaque couche, les paramètres d’appel sont sujets de
changement. Chaque couche ajoute une surcharge à l’appel, ce qui rend
l’appel plus lent que dans un système qui n’est pas en couches.
OS/2, descendant direct de MSDOS, a été conçu en couches comme le montre la
figure1.5 :

APPLICATION APPLICATION APPLICATION


USER MODE

KERNEL MODE

FILE SYSTEM

MEMORY AND I/O DEVICE MANAGEMENT

PROCESSOR SCHEDULING

HARDWARE

Figure1.5 : la structure de OS/2


6.3 Machines virtuelles

L’approche en couches a abouti au concept de la machine virtuelle. La figure1.6


montre une telle structure. Le noyau se charge de la multiprogrammation et fournit
plusieurs machines virtuelles. Ces machines sont des modèles logiques de la machine
réelle. Chaque machine virtuelle exécute n’importe quel système d’exploitation.
L’avantage est que les diverses ressources du système sont totalement protégées.
Chaque machine virtuelle est entièrement isolée des autres, il n’existe pas de
problème de sécurité. Il n’y a aucun partage direct des ressources. Il est possible de
définir un réseau de machines virtuelles communiquant entre elles.

© W. KADRI 13
USER 1 USER 2 USER 3 USER 4

CMS CMS CMS CMS


MACHINE MACHINE VIRTUELLE MACHINE VIRTUELLE MACHINE
VIRTUELLE NOYAU LOCAL NOYAU LOCAL VIRTUELLE
NOYAU LOCAL NOYAU LOCAL
Noyau
MULTIPROGRAMMATION
GESTION DES MESSAGES
MATERIEL

Figure1.6 : Système en machines virtuelles

6.4 Client/serveur

L’idée est de décomposer le système en un ensemble de processus clients et serveurs,


chacun des processus serveurs implémente un ensemble de services, par exemple les
services de gestion de la mémoire, des processus ou du scheduling. Chaque serveur
tourne en mode utilisateur, exécutant une boucle qui vérifie toujours s’il y a des
requêtes de services des clients. Le client qui peut être un autre composant (serveur)
du système d’exploitation ou une application utilisateur exprime ses requêtes de
services par envoi de messages aux serveurs. Un noyau tournant en mode kernel
(noyau) gère la communication et le transfert des messages entre les différents
éléments (clients et serveurs). Chaque processus peut s ‘exécuter sur un processeur
distinct, ce qui rend le système adaptable à une structure distribuée. Ce modèle se
prête bien aux réseaux et systèmes répartis.

Processus Processus Serveur Serveur Serveur Serveur


client client Processus Mémoire Fichiers Terminaux

NOYAU

MATERIEL

Figure1.7 : Le modèle client/serveur

6.5 Modèle hybride

Ce modèle est une combinaison des modèles précédents. Il se base surtout sur le
modèle en couches et sur le modèle client/serveur. Le système se décompose
généralement en une couche d’abstraction du hardware ce qui constitue la machine
virtuelle, d’un noyau et d’un exécutif. Le noyau implémente les fonctions de bas
niveau tout comme le noyau du modèle client/serveur. Il comprend le scheduling
des threads, la gestion des interruptions et la synchronisation multiprocesseur. Il

© W. KADRI 14
comprend également un ensemble de routines et d’objets de base nécessaire à
l’exécutif.

POSIX OS/2 Win32 Security Win32


Subsystem Subsystem Subsystem Subsystem Client

SYSTEM CALLS

Object Process Memory Security I/O


Manager Manager Manager Manager System

KERNEL
HARDWARE ABSTRACTION
LAYER

HARDWARE
Figure1.8 : Windows NT, un modèle hybride

7. APPELS SYSTEMES

Pour mettre en œuvre les principes énumérés ci-dessus le système d'exploitation


reçoit le monopole de certaines opérations, dites opérations privilégiées : allouer des
ressources, déclencher et contrôler des opérations d'entrée-sortie, d'autres que nous
verrons ultérieurement. Mais les programmes ordinaires risquent d'être
singulièrement limités si par exemple ils ne peuvent pas faire d'entrées-sorties : il n'y
aurait par exemple plus de logiciel de traitement de texte possible parce qu'il ne
serait autorisé ni à recevoir le texte frappé au clavier par l'utilisateur, ni à l'afficher à
l'écran, ni à l'imprimer.

Lorsqu'un processus ordinaire a besoin d'effectuer une opération privilégiée il


demande au système d'exploitation de la réaliser pour son compte, et éventuellement
de lui renvoyer le résultat. Cette demande de service est nommée un appel système.
Les opérations privilégiées sont considérées comme des primitives du système
d'exploitation, qui peuvent être invoquées par les programmes ordinaires pourvu
qu'ils soient dotés des autorisations adéquates.

© W. KADRI 15
D’après les structures des systèmes précédentes les appels système peuvent être
divisés en plusieurs catégories selon les modules ou serveurs des couches inférieures.
Grossièrement, ils sont représentés en cinq catégories.
 Processus :
 Arrêter (end) , stopper un processus (abort)
 Charger (load), exécuter un processus(execute)
 Créer (fork) ,terminer(exit)
 Obtenir(get, set process attib), définir des attributs
 Attendre un certain temps(wait time)
 Attendre , signaler des événements( wait, signal )
 Allouer, libérer la mémoire(alloc, dealloc)
 Fichiers :
 créer , supprimer (create, delete)
 ouvrir , fermer (open, close)
 lire, écrire, repositionner (read, write, reposition)
 obtenir, définir des attributs(get ,set file attributes)
 I/O :
 demander, libérer des périphériques(request, release)
 obtenir, définir des attributs de périphériques (get, set)
 attacher, détacher attach, detach)
 Information :
 date et heure (date, time)
 données système (get, set)
 processus, fichiers, périphériques (get,set)
 Communication :
 créer, supprimer des connexions(open , close)
 envoyer, recevoir des messages(send receive)
 transférer des informations sur les états(get , set)
 attacher, détacher des périphériques à distance

© W. KADRI 16
Deuxième Chapitre
GESTION DES PROCESSUS

1- INTRODUCTION
Du point de vue du système, un programme est considéré comme une entité active
qui consomme des ressources, et qui pour les obtenir entre en concurrence avec
d'autres demandes. Le programme vu sous cet angle est appelé un processus (process
en anglais). Le concept de processus est le plus important dans un système
d’exploitation. C’est une abstraction d’un programme en exécution. La conception et
la réalisation de tout système repose, essentiellement, sur ce concept, pour cause, les
systèmes d’exploitation ne reconnaissent d’autres entités exécutables que les
processus.

Le système d'exploitation (operating system, OS) est un programme qui arbitre les
demandes de ressources des différents processus et les satisfait en se conformant à
une stratégie. La stratégie mise en œuvre par le système vise à satisfaire plusieurs
impératifs :

 assurer le fonctionnement correct de l'ordinateur, et donc du système lui-


même : une allocation incohérente de ressources cruciales comme le temps de
processeur ou la mémoire peut provoquer un blocage ou un arrêt complet du
système ;
 distribuer les ressources de telle sorte que tous les processus « correctement
configurés» en reçoivent une allocation suffisante pour s'exécuter «
normalement » ;
 corollaire des deux points précédents : empêcher qu'un processus «
pathologique » n'accapare des ressources cruciales et ne réduise les autres à la
« famine » ;
 assurer à chaque processus l’utilisation paisible des ressources qu'il leur a
allouées, et pour cela établir une protection étanche entre les domaines des
différents processus, tout en leur permettant de communiquer entre eux s'ils
ont été programmés à cet effet. En d'autres termes, c'est au système
d'exploitation que revient d'assurer la sécurité de l'ensemble du système
informatique.

Etant l'activité résultante de l'exécution d'un programme séquentiel, le processus


réunit deux types d'attributs : certains sont de nature plutôt statique, ce sont les

© W. KADRI 17
ressources utilisées (espace mémoire, fichiers ouverts), et d'autre plutôt dynamiques,
c'est essentiellement ce que nous pouvons appeler un « fils » d'exécution pour un
programme (un thread en anglais). Une tendance récente des architectes de systèmes
vise à séparer les deux types d'attributs, en considérant le processus comme un
ensemble de ressources qu'utilisent un ou plusieurs fils d'exécution.

Un processus est caractérisé par :


 une image binaire représentée par un fichier exécutable pouvant être chargé
en mémoire
 un contexte d’exécution
 code
 valeurs de registres, caches processeur
 un espace mémoire
 données (variables globales, locales , constantes)
 espace mémoire virtuel
 un ensemble de ressources

2. CONTEXT D’UN PROCESSUS

Un processus est un programme en exécution. Il est défini par son PCB (Process
Control Block) qui représente le contexte du processus, son code, ses données et sa
pile (fig.3.1).

Fig.3.1 Structures d’un processus

2.1 PCB
Le PCB contient toutes les informations nécessaires à la commutation de contexte
regroupées sous forme compactée pour faciliter leur transfert vers les registres du
processeur. Il spécifie :

 L’état du processus
 Le PC et le PSL
 Les registres du processeur
 Une partie réservée pour l’ordonnancement (le scheduling en anglais)
 La priorité du processus

© W. KADRI 18
 Les pointeurs sur les files d’attente du Scheduling
 Autres informations nécessaires au Scheduling
 Une partie réservée pour la gestion de la mémoire
 Le pointeur sur le code (table des pages du code)
 Le pointeur sur les données
 Le pointeur sur la pile
 Autres informations nécessaires à la gestion de la mémoire
 Une partie pour la comptabilisation
 La priorité du processus
 Les limites de temps
 Le temps CPU et le temps réel utilisé
 Identité du processus etc..
 Une partie pour les E/S
 Les périphériques alloués au processus
 Les fichiers ouverts par ce processus
2.2 Code

C’est un segment constitué de plusieurs pages en mémoire renfermant le code du


programme à exécuter par le processus.

2.3 Data

C’est un segment qui renferme les données manipulées par le processus. En général,
on affecte le même espace pour les data et la pile.

2.4 Stack

La pile est utilisée par un processus, surtout, lors de l’appel de sous programme, car
on doit sauvegarder l’état du programme appelant avant de passer la main au
programme appelé. Elle dispose d’un pointeur de sommet de pile et d’une adresse
début en mémoire.

3. ETAT D’UN PROCESSUS

Nous avons dit que le système d'exploitation, avec l'aide de dispositifs appropriés du
matériel, et en s’appuyant sur le rôle fondamental que possèdent les interruptions
pour le fonctionnement de la multiprogrammation, permettait, ainsi, que chaque
programme s'exécute à son tour, en pseudo-simultanéité avec les autres. Il pouvait
répartir le temps du processeur entre plusieurs processus pseudo-simultanés. Ceci
suppose qu'un processus tout au long de son exécution change d’état d’un instant à
un autre. A un instant donné, il peut être dans l'état actif (Prêt), à un instant suivant
dans l'état dormant (Bloqué), puis encore à un autre instant redémarrer (Elu). Ceci est
décrit par la figure 3.2 suivante :

© W. KADRI 19
Nouveau Admis Exit
Terminé
Suspendu par le scheduler

Prêt Élu
PrPêtPret
Sélectionné par le scheduler
Ressource disponible
en attente de ressource
Bloqué

Figure3.2 Diagramme des états d’un processus

Les états d’un processus sont définis comme suit :


 Nouveau: processus en cours de création pouvant être admis par le système.
 Terminé : processus terminant son exécution et quittant le système.
 Elu : processus en cours d’exécution occupant le processeur.
 Prêt : processus en attente d’élection pour un processeur par le Scheduler.
 Bloqué: processus attendant un événement de mise en disponibilité de ressource.

Le processus suit les transitions suivantes :


 Admis : processus accepté par le système.
 Exit : processus quittant le système.
 Suspendu par le Scheduler : processus disposant de toutes les ressources mais
le Scheduler décide d’exécuter un autre processus (fin de quantum par
exemple).
 Sélectionné par le Scheduler : le Scheduler choisit ce processus.
 Ressource disponible : l’événement signalant la disponibilité d’une ressource
ayant provoquée la suspension du processus a eu lieu. Le processus n’a plus
de rester bloqué.
 En attente de ressource : le processus demande une ressource non disponible.
Il passe dans un état d’attente de ressource. Cet état se distingue selon le
nombre de ressources.

Nous pouvons concevoir qu'un processus actif puisse se mette volontairement à l'état
dormant, par contre, l’inverse n’est pas possible. En effet, le passage de l'état
dormant à l'état actif suppose l'intervention du système d'exploitation ou d'un autre
processus pour réveiller le processus endormi. Comment cela peut-il se passer ?
Nous allons l’expliquer à travers le déroulement d'une opération d'entrée-sortie,
lecture ou écriture sur support externe.

Demande d'entrée-sortie

Comme nous l’avons préciser, les opérations d'entrée-sortie sont des opérations
privilégiées, du ressort du système d'exploitation. Lorsqu'un logiciel veut effectuer

© W. KADRI 20
une entrée-sortie il doit effectuer un appel système. Pour réaliser cette opération
d'entrée-sortie plusieurs composants de l'ordinateur et du système entrent en jeu :

 Le programme effectue un appel système.


 Le système exécute un programme spécial, dit pilote de périphérique (driver),
qui transmet la demande au contrôleur du périphérique physique.
 Le périphérique physique effectue l'action réelle : lire, écrire, enregistrer,
imprimer, émettre un son... Puis il prévient le contrôleur quand il a fini en
émettant un signal d’interruption . Le diagramme des opérations est décrit par
la figure 3.3.

Figure 3.3 : Diagramme d'une opération d'entrée-sortie (E/S)

 Le programme s'exécute normalement, puis il émet une demande d'entrée-


sortie (un appel système).
 Immédiatement après la demande d'entrée-sortie le programme se met
volontairement en attente, en sommeil. La mise en sommeil se fait par un
appel système qui transfère le contrôle au superviseur après avoir sauvegardé
en mémoire le contexte d'exécution du processus (PSW, registres).
 Pour que cette mise en sommeil ne soit pas définitive il faut prévoir un
mécanisme de réveil. En effet un programme qui s'est arrêté ne pourra pas se
remettre en action spontanément. L'appel système (sleep ou wait selon les cas)
place à un endroit connu du système les informations qui permettront, lorsque
l'E/S sera terminée, de savoir quel processus réveiller et quelle information lui
donner.
 La demande d'entrée-sortie est prise en charge par le système, qui s'empresse
de la mettre en file d'attente. Sur un système en multiprogrammation les
demandes d'entrée-sortie sont en effet multiples et il faut y mettre un ordre.
 La partie du système chargée de traiter les demandes d'entrée-sortie va, plus
tard, extraire notre demande de la file et la traiter en la transmettant au
contrôleur, qui la transmettra, à son tour, au périphérique physique. Et là
commencera l’exécution de l'action elle-même.

© W. KADRI 21
Interruption de fin d'entrée-sortie

Puis l'entrée-sortie suit son cours, et viendra le moment où le périphérique (disque


dur, clavier, écran...) aura fini son travail. Comment le signaler au programme
interrompu ? Celui-ci est dormant, il ne peut recevoir d'information. Il faut donc
passer par l'intermédiaire du système d'exploitation.

Le périphérique envoie au contrôleur un signal pour le prévenir, quelques


informations qui constituent un compte-rendu d'exécution de la tâche, et
éventuellement les données qui lui étaient demandées. Une fois les données placées
au bon endroit en mémoire, le contrôleur envoie sur une ligne de signalisation
particulière un signal qui va déclencher une interruption du processeur.
L'interruption est un mécanisme capital pour la synchronisation des ordinateurs,
nous allons en exposer le principe.

 Le signal d'interruption a deux effets :

 il interrompt, donc, le programme en cours d'exécution ;


 le PSW courant est sauvegardé en mémoire et remplacé par un
nouveau PSW qui comporte une valeur de PC qui pointe vers une
section particulière du système, le superviseur d'interruption ; c'est
donc ici que va se continuer l'exécution.

 La première chose que fait le superviseur d'interruption est de déterminer la


nature de l'interruption. Ici le signal lui donne la réponse : interruption
d'entrée-sortie, qui est provoquée par un élément matériel extérieur au
processeur, indépendant du cadencement des instructions. C'est une
interruption asynchrone. Il existe par ailleurs des interruptions provoquées par
le processeur lui-même, par exemple lorsqu'il détecte une condition anormale,
ou simplement à la demande d'un programme. Ces interruptions sont
synchrones, parce que le processeur ne les produit qu'après avoir terminé
l'exécution d'une instruction, et elles sont aussi nommées exceptions. Il se
débranche, donc, à la section appropriée, le superviseur d'interruption
d'entrée-sorties.

 Une fois le contrôle transféré au superviseur d'interruption d'entrée-sortie,


celui-ci retrouve dans ses tables la référence du drapeau associé à la demande
d'entrée-sortie concernée, par là il retrouve la structure de données qui la
décrit, puis le processus dormant qui l'avait émise.
 Le superviseur fait passer le processus émetteur de l'état dormant à l'état prêt,
c'est-à-dire candidat à redevenir actif, éligible pour l'exécution.
 Le superviseur d'interruptions passe ensuite la main à une autre partie du
système, l'ordonnanceur, ou programmateur (en anglais scheduler).

© W. KADRI 22
4. COMMUTATION DE CONTEXTE (CONTEXT SWITCHING)

Le contexte d'un processus est l'ensemble des informations dynamiques qui


représente l'état d'exécution d'un processus (e.g. où est-ce que le processus en est de
son exécution).

La commutation de contexte est le mécanisme qui permet au système d'exploitation


de remplacer le processus élu par un autre processus Prêt.
Le temps nécessaire à la commutation de contexte doit être inférieur au quantum.
Le fait de retirer le CPU à un processus et l’affecter à un autre est le context switching
« commutation de contexte » (fig 3.4). Le temps pris par cette opération est important
et touche aux performances du système. Le context switching dépend de la rapidité
de la mémoire et de l’existence d’instructions spéciales (chargement et sauvegardes
des PCB en une seule instruction machine). Il varie de 1 à 100ms.

Processus P0 Système Processus P1

Sauvegarde de PCB0

Chargement de PCB1 Inactif

Inactif Interruption ou appel système en exécution

Sauvegarde de PCB1

Inactif
Chargement de PCB0

Figure3.4: Context Switching

© W. KADRI 23
5- IMPLEMENTATION DU MODELE DE PROCESSUS

Tout système d’exploitation est représenté par un ensemble de processus. Certains


sont des processus système et les autres sont des processus utilisateurs. Ils sont
organisés selon figIII.4

Process Process Process Process Process Process


0 1 2 ... n-2 n-1 n

SCHEDULER
Figure3.5: Modèle de processus

La couche la plus basse d’un système structuré en processus se charge des


interruptions et effectue le Scheduling. Le reste du système est constitué de
processus.

La gestion des interruptions, la suspension et la relance des processus selon le


diagramme des états font partie intégrante du Scheduling. Cette couche porte le nom
de noyau de synchronisation ou tout simplement KERNEL.

Dans un modèle de processus, le schéma suivant est toujours respecté suite à une
interruption :

 Empilement du PC et PSL (opération hardware)


 Chargement du nouveau PC à partir du vecteur de l’interruption (hardware)
 Exécution de la routine d’it
 Sauvegarde des registres du processeur dans le PCB
(assembleur)
 Sélection de la nouvelle pile (assembleur)
 Changement de l’état du processus (driver d’E/S) à prêt (C)
 Sélection du processus par le Scheduler
 Fin de la procédure C
 Lancement du processus élu par la routine assembleur

6- NOTION DE THREADS

Il existe plusieurs situations où il serait utile de partager des ressources et de pouvoir


y accéder d’une manière concurrentielle. La routine d’accès à la ressource peut être
implémentée sous forme de thread s’exécutant dans le même espace d’adresse que le
processus accédant à cette ressource via la routine. Un processus est constitué de
plusieurs threads partageant les mêmes données, la pile et parfois le même code.

Durant son exécution, un processus utilise le processeur pour y exécuter du code.


Généralement le code est un enchainement d'instructions machines les unes à la suite
des autres avec des sauts de part et d'autres dans le code. Et ce code suit son petit
chemin.

© W. KADRI 24
On appelle cela un fil d'exécution. Un processus a toujours au moins un fil
d'exécution, qu’on appelle, aussi, thread. Et s'il le veut, un processus peux avoir
plusieurs codes qui s'exécutent en même temps, donc, plusieurs fils d'exécution.
Dans ce cas, on dit que ce processus possède plusieurs threads ou encore qu'il est
multithread. Grossièrement c'est un peu comme si un programme exécutait plusieurs
sous-programme simultanément.

La structure de données représentant un thread est définie par :


 son propre identificateur
 une politique et une priorité d'ordonnancement
 une partie privée : ,
Pile d'exécution,
Valeur de registre,
Mémoire locale
 une partie partagée : texte du programme,
 variables statiques, fichiers ouverts, sockets, etc....

TCB Code
Stack
Data
Thread Control
Block

Figure 3.6: Structure d’un thread

Un thread peut être dans l'un des états suivants :


 Ready : le thread est en attente d’exécution
 Stand by : un thread parmi les Readys est sélectionné pour s’exécuter sur un
processeur. Un thread par processeur. Le dispatcher, dans les
conditions convenables, exécute le context switching. Un seul
thread par processeur peut être dans l’état Stand by.
 Running : Suite au context switching, le thread rentre en exécution jusqu’à ce
que :
 Un thread prioritaire arrive.
 Le quantum expire
 Le thread se termine.
 Il entre volontairement dans l’état waiting
 Waiting : il entre dans cet état si :
 Il attend volontairement un objet pour synchroniser son
exécution..
 Au compte du système I/O

Sur une machine monoprocesseur, un seul thread est actif à la fois. Sur une machine
multiprocesseur, plusieurs threads peuvent être actifs (parallélisme réel).

© W. KADRI 25
7. ALGORITHMES DE SCHEDULING

Les systèmes que nous envisageons permettent la multi-programmation, c'est-à-dire


que plusieurs processus sont à un moment donné en concurrence pour disposer du
processeur. Pour permettre cette concurrence, il faut que le système soit capable de
retirer le contrôle du processeur à un processus pour le donner à un autre. La partie
du noyau du système qui fait cela est l'ordonnanceur ou programmateur (en anglais
scheduler).

Le rôle de l'ordonnanceur est de sélectionner parmi les processus prêts celui qui va
être activé. La méthode de sélection peut dépendre de plusieurs paramètres : délai
d'attente déjà écoulé pour chaque processus, niveau de priorité, etc. Puis
l'ordonnanceur passe la main au distributeur (en anglais dispatcher), qui remet
effectivement en activité le processus sélectionné en restaurant son contexte
d'exécution (PSW, registres). Sa fonction inclut :

 Le context switching
 Changement du mode user au mode kernel
 Initialisation du PC par l’adresse début du programme utilisateur.

On utilise souvent le diagramme des processus de la fig.3.6 pour représenter et


expliquer le scheduling.
 Ready Queue : renferme tous les processus prêts en attente d’exécution.
 Device Queues : renferment par classe l’ensemble des processus en attente de
ressources. Pour chaque type d’E/S, il existe une liste associée.

Un nouveau processus est placé dans la Ready Queue, il attend dans cette liste sa
sélection pour l’exécution. Quand il dispose du processeur (élu) un parmi les
événements suivants se produit :
 Le processus demande une I/O, il est placé dans la I/O Queue.
 Le processus crée un fils et attend qu’il termine.
 Le processus doit être forcé de quitter le CPU suite à une interruption (ou le
temps expire)
Le processus continue dans ce diagramme jusqu’à sa fin.

In
Ready Queue CPU
Out
I/O Queue
I/O I/O Request

Time Sclice expires

Child terminates Child executes Fork a child

Interrupt occurs Wait for an interrupt

Figure 3.6 : Diagramme des transitions


© W. KADRI 26
8. CRITERES DE PERFORMANCES

Comme nous l’avons déjà vu au préalable, l’ordonnanceur (scheduler) permet de


garantir une exécution concurrente de plusieurs tâches sur la base de plusieurs
stratégies ou algorithmes. Du choix de l'algorithme d'ordonnancement dépend le
comportement du système. Les critères d’évaluation des algorithmes sont :

 taux d'utilisation du processeur;


 débit: nombre de tâches prises en compte pendant une période donnée;
 temps d'exécution appelé aussi le temps de rotation (Turnaround time en
anglais) le temps depuis le lancement du processus jusqu’à sa terminaison (les
attentes incluses). Ce temps est la somme du temps CPU, du temps passé à
l'état prêt et celui passé à l'état endormi (plus le temps de chargement);
 temps d'attente moyen: temps d’un processus dans la file d’attente des
processus prêts ce critère concerne le temps moyen passé à l'état prêt;
 temps de réponse: ce critère concerne le temps moyen mis entre une requête
émise et la première réponse de prise en compte d'une requête.
 Le temps de latence : temps pris par le dispatcher pour stopper un processus
et relancer un autre

Pour qu’un algorithme soit optimal il faut qu’il réponde aux critères suivants:
 Utilisation maximale du CPU
 Débit maximum
 Temps de rotation minimal
 Temps d’attente minimal
 Temps de réponse minimal

Ces cinq critères sont plus ou moins mutuellement exclusifs. Les comparaisons des
différents algorithmes se fait donc sur une sélection de ces différents critères.

9. ALGORITHMES DE SCHEDULING :

Il existe deux types de schedulers :


 Le job scheduler : souvent appelé long term scheduler, sélectionne le job et le
ramène en mémoire pour exécution.
 Le CPU scheduler : ou short term scheduler, sélectionne parmi les processus
prêts, le plus approprié et lui alloue le CPU.

Le scheduler doit décider quand un processus change d’état et passer par les
différentes transitions :de l’état Elu à l’état Bloqué, de l’état Elu à l’état Prêt, de l’état
Bloqué à l’état Prêt et enfin quand il se termine.

Le Scheduler peut être :


 Non préemptif : Une fois le CPU alloué à un processus, celui-ci le
retient jusqu’à la fin de son exécution ou jusqu’à passer à
un état bloqué (décisions 1 et 4).

© W. KADRI 27
 Préemptif : À chaque interruption, le CPU prend la main. Renferme les
décisions 1 à 4.

9.1 Tourniquet (round robin)

La solution d'ordonnancement la plus simple consiste à découper le temps en


tranches, appelé quantum, et à dire qu'aucun processus ne pourra avoir la main
pendant deux tranches de temps consécutives. Chaque expiration d'une tranche de
temps déclenche une interruption et donne la main à l'ordonnanceur, qui peut ainsi
éviter la monopolisation du processeur par un programme gourmand.

La Ready-queue est gérée par la politique de gestion First-In-First-Out et est


circulaire. Les nouveaux processus sont ajoutés en queue de liste.

Input Output
CPU

Le CPU saisit le processus en tête de liste et initialise l’horloge à la valeur du


quantum. Celle-ci se décrémente automatiquement ce qui peut provoquer les
situations suivantes:

 Le temps CPU du processus est inférieur au quantum (q) et le processus


quitte volontairement le CPU avant q. On passe au processus suivant.
 L’horloge atteint 0 et émet une interruption qui provoque un context
swiching. Le processus en cours passe en queue de liste car son temps CPU
dépasse son quantum q. Le tête de liste est sélectionné.

Exemple :
Processus temps CPU
P1 24
P2 3
P3 3
Si on considère que l’ordre d’arrivée est P1, P2, P3 à t=0 et que le quantum q=4 alors
le diagramme de Gantt est :

P1 P2 P3 P1 P1 P1 P1 P1
0 4 7 10 14 18 22 26 30

P1 P2 P3 moyen
Temps attente 6 4 7 5.6
Turnaround 30 7 10 15.6

© W. KADRI 28
9.2 FCFS (First-Come-First-Served) (premier arrivé, premier servi)
Le FCFS utilise une file d’attente simple où le premier venu est le premier servi.

Input output
CPU

Exemple :
Processus temps CPU
P1 24
P2 3
P3 3
Si on considère que l’ordre d’arrivée est P1, P2, P3 , le diagramme de Gantt est :

P1 P2 P3
0 24 27 30

P1 P2 P3 moyen
Temps attente 0 24 27 17
Turnaround 24 27 30 27
9.3 SJF (Shortest-Job-First) (le plus court en premier)
Le SJF utilise une file ordonnée selon le temps d’exécution croissant (le plus court en
tête de liste et le plus long en queue de liste). Si deux processus possèdent le même
temps estimé, ils sont traités en FCFS. L’estimation est faite à priori.

Output
CPU

Input

Temps CPU

Exemple1 : SJF Non Préemptif


Processus temps CPU
P1 6
P2 8
P3 7
P4 3

P4 P1 P3 P2
0 3 9 16 24

P1 P2 P3 P4 Moyen
Temps attente 3 16 9 0 7
Turnaround 9 24 16 3 13

© W. KADRI 29
Exemple2 : SJF Préemptif
Processus temps CPU Temps d’arrivée
P1 8 0
P2 4 1
P3 9 2
P4 5 3

P1 P2 P4 P1 P3
0 1 5 10 17 27

P1 P2 P3 P4 Moyen
Temps attente 9 0 15 2 6.5
Turnaround 17 4 25 7 13.25

9.4 Priorité (Priority) :


Cette solution consiste à affecter à chaque processus une priorité. L'ordonnanceur
donne toujours la main au processus prêt (dispatchable) de plus haute priorité. Il
suffit, par exemple, de donner une priorité basse aux processus qui font peu
d'entrées-sorties et une priorité haute à ceux qui en font beaucoup, et dont on sait
qu'ils vont se mettre en attente « volontairement ». Les processus de même priorité
obéissent à un FCFS. La priorité la plus élevée est définie par convention. 0 peut être
la plus haute ou la plus basse selon les systèmes. Les nouveaux processus sont placés
dans la file selon leur priorité.

Output
CPU

Input

priorité

Exemple1 : Priority Non Préemptif


Processus temps CPU Priorité
P1 10 3
P2 1 1
P3 2 3
P4 1 4
P5 5 2

P2 P5 P1 P3 P4
0 1 6 16 18 19

P1 P2 P3 P4 P5 moyen
Temps attente 6 0 16 18 1 8.2
Turnaround 16 1 18 19 6 12

© W. KADRI 30
Exemple2 : Priority Préemptif
Processus temps CPU Priorité Temps d’arrivée
P1 8 3 0
P2 4 2 1
P3 9 1 2
P4 5 3 3

P1 P2 P3 P2 P1 P4
0 1 2 11 14 21 26

P1 P2 P3 P4 moyen
Temps attente 13 9 0 18 10
Turnaround 21 13 9 23 16.5

9.5 MQS ( Multilevel Queue Scheduling ) :

Dans cet algorithme, on divise la Ready queue en plusieurs listes. Cette division
dépend du type de processus et de ces propriétés telles que la taille de la mémoire
etc…
Exemple :
Highest priority
System processes

Interactive processes

Batch processes

Student processes

Chaque liste dispose de son propre algorithme de scheduling. Il faut en plus un


scheduling entre les listes. Les processus sont assignés à une liste et y restent jusqu’à
la fin de leur exécution. Mais cette approche n’est pas flexible (le processus ne peut
changer de liste).

9.6 MFQS ( Multilevel Feedback Queue Scheduling ) :

MFQS permet à un processus de changer de listes. L’idée est basée sur le temps CPU
nécessaire au processus. Si un processus nécessite beaucoup de temps, il décroît dans
les listes jusqu’à la moins prioritaire. Un processus qui a beaucoup attendu dans une
liste peut grimper vers les priorités supérieures.

© W. KADRI 31
Exemple :
Considérons un MFQS à 3 listes F0, F1,F2.

F0
q=8

q=16 F1

FCFS F2

Tout nouveau processus est servi dans la liste F0. Si F0 est vide le scheduler exécute
F1. Si F1 est également vide, il exécute F2.

Si un processus arrive dans F0 ,il exécute la préemption des processus de F1 ( tous les
processus de F1 sont suspendus) et dispose du CPU. Egalement un processus
arrivant dans F1 fait la même chose avec les processus de F2 .

Un processus de F0 a un quantum q=8ms. S’il nécessite plus de 8ms, il passe dans F 1.


quand F0 devient vide, les processus de F1 (en particulier le processus arrivant de F0)
sont pris en compte prenant chacun un quantum q=16ms. S’il ne se termine pas, il
passe dans F2 où il séjourne jusqu’à ce que F0 et F1 deviennent vides. On applique
alors à F2 un FCFS.

Un MFQS est défini par :

 Le nombre de listes.
 L’algorithme de scheduling de chaque liste.
 La méthode utilisée pour dégrader un processus.
 La méthode utilisée pour favoriser un processus.
 L’algorithme utilisé pour déterminer la liste appropriée.

Il est possible de combiner toutes ces stratégies de répartition du temps de


processeur pour obtenir un système auto-régulé. Nous aurons des tranches de temps
et des priorités, qui de surcroît seront variables dynamiquement. Un processus aura
deux façons de s'interrompre : soit « volontairement » en faisant une demande
d'entrée-sortie ou tout autre appel système suivi d'une mise en attente, soit en
atteignant la fin d'une tranche de temps. L'ordonnanceur se voit attribuer une
prérogative supplémentaire : les « bons » processus qui se seront interrompus «
volontairement » verront leur priorité augmentée, les « mauvais » processus qui
auront atteint la limite d'une tranche de temps, manifestant par là une tendance
néfaste à la monopolisation, verront leur priorité diminuée, ce qui améliorera la
fluidité de la multiprogrammation.

La multiprogrammation permet d'améliorer le taux d'allocation du processeur.


Supposons qu'un processus passe une fraction p de son temps à attendre la fin d'une
opération d'E/S. Si n processus se trouvent en mémoire en même temps, la

© W. KADRI 32
probabilité qu'ils soient tous en attente sur une E/S (et donc le CPU en Idle State) est
pn. L'utilisation du CPU est 1-pn .

Considérez un ordinateur de 1 Mo de mémoire, où le SE et les processus occupent


chacun 200 Ko. Si on attend en moyenne 80% du temps sur des E/S, le taux
d'utilisation du processeur (sans tenir compte de l'overhead) est d'environ 60%. 1 Mo
supplémentaire fait passer le degré de multiprogrammation de quatre à neuf et le
taux d'utilisation du processeur à 87%. Autrement dit, le deuxième méga-octet
améliore le rendement de 45%. Un troisième méga-octet fait passer le taux
d'utilisation du processeur de 87 à 96%, ce qui améliore le rendement de seulement
10%. Le modèle permet donc de voir que le deuxième méga-octet de mémoire vive
est justifié, mais peut-être pas le troisième.

© W. KADRI 33
Troisième Chapitre
GESTION DE LA MEMOIRE

1- INTRODUCTION
Au début de l'informatique les mémoires étaient chères et de petites tailles. A cette
époque les programmeurs passaient l'essentiel de leur temps à optimiser leur
programme en fonction de la taille mémoire. On a ensuite pu utiliser une mémoire
secondaire : bandes, tambours et disques. Le programmeur divisait, alors, son
programme en un certain nombre de morceaux appelés branches (overlays), chaque
branche étant de taille inférieure à celle de la mémoire. Pour exécuter un programme
on chargeait la première branche puis la seconde et ainsi de suite. Le programmeur
était totalement responsable de la découpe du programme, de la gestion et de la
migration des branches entre la mémoire principale et la mémoire secondaire.
En 1961 des chercheurs de Manchester ont proposé une méthode qui permettait de
rendre transparent au programmeur le mécanisme de gestion des branches. Au
début des années 1970 cette technique, dite de mémoire virtuelle, devint disponible
sur la plupart des ordinateurs. L'idée consiste à distinguer les notions d'espace
d'adressage et d'emplacement mémoire.
Dans ce chapitre nous abordons la problématique de la gestion de la mémoire dans
les systèmes d'exploitation. Nous abordons, d’abord, les aspects matériels de la
mémoire, en particulier les questions concernant les architectures des ordinateurs :
pourquoi les ordinateurs ont-ils plusieurs types de mémoire, qu’est-ce que la
mémoire virtuelle, entre autres.

2. DESCRIPTION DE LA MEMOIRE

La mémoire physique sur un système se divise en deux catégories :


 la mémoire vive : composée de circuit intégrés, donc très rapide
 la mémoire de masse : composée de supports magnétiques (disque dur,
bandes magnétiques...), beaucoup plus lente
La mémoire physique sert de zone de stockage temporaire pour les programmes et
les données. De façon générale, plus la quantité de mémoire est importante, plus il
est possible de lancer plusieurs applications simultanément. D'autre part, plus celle-
ci est rapide plus le système réagit vite, il s'agit donc (pour le système d'exploitation)
de l'organiser et la gérer au mieux pour en tirer le maximum de performances.
Lorsque l'on travaille sur des processeurs simples, on gère la mémoire de façon
primaire. C’est-à-dire que lorsque le programmeur écrit une application, il gère lui-
même les adresses utilisées en RAM par son code et par les données manipulées par
ce code. Par contre, sur une architecture avancée de type Intel, par exemple (mais
aussi PowerPC ou autre), la gestion de la mémoire est dite "virtuelle".

Le programmeur travaille avec des adresses logiques, théoriques, qui n'ont aucune
relation directe avec les adresses physiques, celles où la RAM est implémentée.
Comme il faut bien tout de même qu'au bout du compte le programme s'appuie sur

© W. KADRI 34
des adresses physiques, un mécanisme de traduction d'adresse est mis en place le
MMU (Master Memory Unit).
Les processeurs Intel de type Pentium disposent d'un bus d'adresses de 32 bits, donc
232 adresses possibles, ce qui fait 4 Go de RAM adressable. Le but à atteindre est de
permettre aux programmeurs de concevoir leur application comme si 4 Go de RAM
étaient disponible, même s'il y en a beaucoup moins en réalité. Le mécanisme de
"swap" (fichier d'échange sur disque) permet d'atteindre cet objectif.

La gestion de la mémoire est un difficile compromis entre les performances (temps


d'accès) et la quantité (espace disponible). On désire en effet tout le temps avoir le
maximum de mémoire disponible, mais l'on souhaite rarement que cela se fasse au
détriment des performances.

La gestion de la mémoire doit de plus remplir les fonctions suivantes :


 permettre le partage de la mémoire (pour un système multi-tâches) ;
 permettre d'allouer des blocs de mémoire aux différentes tâches ;
 protéger les espaces mémoire utilisés (empêcher par exemple à un utilisateur
de modifier une tâche exécutée par un autre utilisateur) ;
 optimiser la quantité de mémoire disponible, notamment par des mécanismes
d'extension de la mémoire.

La gestion de la mémoire est assurée par le gestionnaire de mémoire.


 Le gestionnaire de mémoire est chargé de :
 Connaître les parties libres et occupées de la mémoire
 Allouer de la mémoire aux processus qui en ont besoin
 Récupérer la mémoire utilisée par un processus lorsque celui-ci se
termine
 Traiter le va-et-vient (swapping ) entre le disque et la mémoire
principale lorsque cette dernière ne peut pas contenir tous les
processus.

 Les gestionnaires de mémoire peuvent être divisés en deux classes :


 Ceux qui font le Swapping et la pagination
 Ceux qui ne les font pas

2.1- UNITE D'ADRESSAGE

L'unité d'adressage est la plus petite quantité de mémoire qui sépare deux adresses
consécutives. Dans toutes les machines, par convention, on assigne à la première
position de mémoire l'adresse 0, à la deuxième l'adresse 1 et à la Nième l'adresse N-1.
Une machine peut être adressable par octet (byte) ou par mot de 16, 20, 32, 60, 64, …
bits. Dans une machine adressable par octet, un mot de 32 bits est constitué de 4
octets consécutifs. Mais les constructeurs ont adopté deux conventions différentes
pour ranger les octets à l'intérieur d'un mot. Dans la première convention l'octet qui
contient les 8 bits de poids faible du mot est rangé à l'adresse la plus basse. Il est
rangé à l'adresse la plus haute dans le second cas. Ces deux conventions sont parfois
référencées par les vocables de big-endian et little-endian respectivement. Aucune de

© W. KADRI 35
ces deux conventions n'est intrinsèquement meilleure que l'autre. Cela n'a
d'importance que lors d'un échange de données entre deux machines respectant des
conventions différentes. L'adresse du premier octet doit être paire, voire même un
multiple de 4.

2.2- ESPACE D'ADRESSAGE

L'espace virtuel est le nombre de cellules mémoires qu'un programme peut adresser
directement. Ce nombre dépend du nombre de bits utilisés pour manipuler les
adresses au niveau des instructions. La mémoire physique disponible sur la machine
peut avoir une taille différente de l'espace virtuel disponible pour chaque
programme.
L'espace physique peut être plus grand que l'espace virtuel. Dans cette configuration
il est possible de charger plusieurs programmes à la fois. Lorsque le contrôle de
l'unité centrale passe d'un programme à l'autre, l'exécution peut s'enchaîner
rapidement sans attendre le chargement du nouveau programme depuis le disque.
Comme l'unité centrale accède à la mémoire par des adresses comptant un plus
grand nombre de bits que les adresses manipulées par le programme il faut être
capable de "compléter" celles-ci. Cela peut se faire grâce aux registres de base dont
nous parlerons plus loin.
L'espace physique peut être plus petit que l'espace virtuel. Dans ce cas il faut
disposer d'un mécanisme capable de charger, à un moment donné, les parties du
programme nécessaires à son exécution. Ce mécanisme est également utilisé dans des
machines pour lequel l'espace physique est plus grand que l'espace virtuel. Il permet
en effet un partage plus efficace de la mémoire entre plusieurs programmes
concurrents.

2.3- PRINCIPE DE LA SEPARATION ET DE L'ASSEMBLAGE DES ADRESSES

Le principe de séparation/assemblage des adresses est le fondement de toutes les


techniques de gestion de la mémoire centrale. Une adresse peut toujours être vue
comme l'assemblage d'un numéro de bloc et d'un déplacement à l'intérieur de ce
bloc :

© W. KADRI 36
Une adresse de N bits permet de repérer 2N cases. On peut la séparer en un numéro
de bloc, codé sur B bits (les bits de poids fort), et un numéro de case dans le bloc sur
N-B bits. Chaque bloc comptera 2N-B cases et il y aura 2B blocs, donc toujours 2N cases
au total.

Prenons un exemple numérique très simple pour illustrer ce principe. Considérons


une mémoire comptant 16 cases, numérotées de 0 à 15. Les adresses permettant
d'identifier les mots dans cette mémoire ont 4 bits. Nous nous intéressons à la case
d'adresse 13 (marquée **** sur la figure). En binaire nous avons 13 = (1101)2. Si nous
divisons la mémoire en deux blocs de huit mots, cette case 13 se situe à l'adresse 5 du
bloc numéro 1 (6ème mot du 2ème bloc). Le numéro de bloc est donné par le bit de
poids fort (à gauche) de l'adresse. Le déplacement dans le bloc est donné par les trois
bits de droite : (101)2 = 5. Nous pouvons également diviser la mémoire en quatre
blocs de quatre mots. Le numéro de bloc est alors donné par les deux bits de gauche
(11)2 = 3 et le déplacement par les deux bits de droite (01)2 = 1. La case 13 est en effet
à l'adresse 1 dans le bloc 3.

Ce principe est facile à mettre en œuvre au niveau du matériel : les B lignes du bus
d'adresse correspondant aux bits de poids fort sont connectées à un registre de B bits
et les N B autres lignes sont commandées par un autre registre de N B bits. Ces
registres peuvent être chargés indépendamment par l'unité de calcul des adresses
effectives.

2.4-REGISTRE DE BASE

Pour optimiser l'utilisation de tout ordinateur il est rapidement devenu


indispensable de pouvoir charger tout programme n'importe où en mémoire. Il faut
donc un mécanisme permettant à partir des adresses virtuelles de calculer les

© W. KADRI 37
adresses physiques. Une des méthodes les plus utilisées est celle des registres de base
qui existent dans presque tous les ordinateurs. Le mécanisme est le suivant :
 Les programmes sont "relogeables" et toutes les adresses connues par le
programmeur sont virtuelles, relatives au début du programme à l'adresse 0;
 Un registre spécial de l'unité centrale, appelé registre de base, contient
l'adresse physique du début du programme dans la mémoire;
 Chaque fois que l'on fait une référence à la mémoire, on ajoute à l'adresse
virtuelle trouvée dans le programme le contenu du registre de base.

Un registre de base permet également de construire des adresses physiques comptant


un nombre différent de bits que les adresses virtuelles.

2.5- Unité de gestion de la mémoire : Le MMU

La plupart des systèmes à mémoire virtuelle ont recours à la pagination. Sur tout
ordinateur, les programmes peuvent générer un certain nombre d'adresses. Les
adresses manipulées par des programmes sont appelées les adresses virtuelles et
constituent l'espace d'adresses virtuelles. Sur les ordinateurs sans mémoire virtuelle,
les adresses virtuelles sont directement placées sur le bus de la mémoire et
deviennent des adresses physiques. Lorsque la mémoire virtuelle est utilisée, les
adresses virtuelles ne sont pas directement placées sur le bus de la mémoire. Elles
sont d’abord traduites par l'unité de gestion de la mémoire ou MMU (Memory
Management Unit) en adresses physiques et ensuite placées sur le bus.
Plus précisément, une MMU (Master Memory Unit en anglais) est un circuit
d'interface sur le bus d'adresse entre le microprocesseur et la mémoire centrale. Dans
la pratique, ce circuit est directement intégré sur le silicium du microprocesseur. La
MMU transforme une adresse entrante, fournie par le microprocesseur, en une
adresse sortante, exploitée par la mémoire.

Le fonctionnement de la MMU est basé sur l'exploitation d'une TLB, Translation


Lookaside Buffer ou table des pages suivant le principe qui suit :
1. Elle décode une adresse placée par le microprocesseur sur le bus d'adresse.
2. En ne considérant que les 20 bits de poids fort sur les 32 bits d'adresse, elle
cherche une équivalence dans la TLB.
3. Si l'équivalence est trouvée, elle forme l'adresse sortante en remplaçant les 20
bits de poids fort par les 20 bits d'équivalence trouvés dans la TLB, les 12 bits

© W. KADRI 38
de poids faible conservés d'une adresse à l'autre constituant le déplacement
dans la page courante.
4. Dans le cas contraire, elle repositionne le PC du microprocesseur sur le début
de l'instruction en cours et génère une interruption.
Toutes les adresses manipulées par des programmes sont des adresses virtuelles
(logiques). Avant d'être appliquées au bus de données, elles passent par la MMU qui
les traduit en adresses physiques. Nous allons schématisé le principe général à
travers l’exemple suivant :

Exemple :
1- supposons que deux applications A et B tournent "en même temps". Elles
n'ont pas besoin de savoir comment elle vont s’exécuter chacune de son côté,
c'est pourquoi certaines adresses logiques peuvent correspondre à l'une
comme à l'autre. Cependant, grâce aux tables de conversions d'adresses, les
deux applications occuperont physiquement des zones de RAM distinctes
figure 4.1.

2- Imaginons maintenant que l'utilisateur démarre une troisième application C.


Elle peut utiliser des adresses logiques déjà employées par A ou B. Le système
doit mettre à jour les tables de translation d'adresses, mais il n'y a plus de
place disponible en RAM physique.

© W. KADRI 39
3- Le système va donc faire de la place, en déplaçant par exemple, le contenu de
la RAM utilisée par l'application A vers le fichier d'échange sur disque dur( il
effectue un swap). Cette place en RAM est maintenant disponible pour
l'application C. Bien entendu, lorsque ce sera au tour de A de reprendre le
travail, il faudra que l'OS restitue la zone de RAM disponible pour A (au
même endroit ou ailleurs, ça n'a aucune importance, du moment que les tables
de translation sont maintenues à jour).

2.6- LE "SWAP"

Le "swap" (échange de zones de données entre la mémoire vive et la mémoire de


masse), intervient donc principalement lorsque la place vient à manquer en mémoire
vive. La procédure est bien entendu assez longue et pénalise lourdement les
performances.

3. LA GESTION DE LA MEMOIRE
3.1 Gestion de la mémoire Sans va-et-vient

Il apparaît nécessaire d’avoir plusieurs processus en mémoire. Pour cela, la méthode


la plus simple est de diviser la mémoire en n partitions fixes, éventuellement de taille
inégale. Le partitionnement peut par exemple, être fait par l'opérateur au démarrage
du système. Quand un job arrive, il est placé dans la liste de la plus petite partition
capable de le contenir. Puisque les partitions sont fixes, tout l’espace de la partition
non utilisé est perdu.

Cette méthode appelée la MFT utilise deux techniques : la MFT à file d’entrée
multiples (a) et la MFT a file d’entrée Unique (b)

© W. KADRI 40
L'organisation de la mémoire en partitions fixes est une méthode facile à mettre en
œuvre pour les systèmes à traitements par lots. Avec les systèmes à temps partagé, la
situation est différente; la mémoire existante utile est inférieure à la taille de tous les
processus, donc, ne pouvant contenir les processus de tous les utilisateurs, il faut
placer quelques processus sur le disque ; et les ramener en mémoire principale avant
de les exécuter. Le mouvement de va-et-vient des processus entre la mémoire
principale et le disque est appelé le swapping.

3.2 - LA GESTION DE LA MEMOIRE AVEC VA-ET-VIENT (SWAPPING)

En pratique, les partitions fixes ne sont pas très intéressantes lorsque la mémoire est
limitée, car on perd beaucoup de place à cause des programmes qui sont plus petits
que les partitions. Avec les partitions variables, le nombre, la position, la taille des
processus en mémoire varient dynamiquement au fur et à mesure qu'ils entrent ou
sortent de la mémoire. Cette méthode appelée la MVT améliore l'usage de la
mémoire mais complique son allocation et sa libération.

On peut réunir les espaces inutilisés (les trous) en une seule partition de grande taille
en déplaçant tous les processus vers le bas de la mémoire. Cette technique s’appelle
le compactage de la mémoire, elle est rarement utilisée parce qu’elle consomme
beaucoup de temps CPU.

L'allocation est simple si les processus ont une taille fixe qu'ils ne modifient jamais :
on alloue exactement la taille requise. Si en revanche, la taille des segments de
données des processus peut varier, par exemple lorsqu'on alloue dynamiquement de
la mémoire dans le tas, on a des difficultés dès qu'un processus demande de la
mémoire. Il existe trois manières de mémoriser l'occupation de la mémoire.
 Les tables de bits (bit maps),
 Les listes
 les subdivisions (Buddy System).

© W. KADRI 41
3.2.1 - GESTION DE LA MEMOIRE AVEC BIT MAPS

La mémoire est divisée en unités d'allocation dont la taille peut varier de quelques
mots à plusieurs Kilo-octets. A chaque unité, on fait correspondre un bit dans la table
de bits qui est à 0 si l'unité est libre et à 1 si elle est occupée (ou vice versa).

La taille de l'unité d'allocation joue un rôle important. Plus elle est faible plus la table
est importante. Si on prend une unité d'allocation de grande taille, on réduit la taille
de la table de bits, mais on perd beaucoup de place mémoire chaque fois que la taille
d'un processus n'est pas un multiple de la taille de l'unité d'allocation. La table de
bits permet ainsi de mémoriser l'occupation de la mémoire dans un espace mémoire
de taille fixe, le seul problème survient lorsqu'on doit ramener en mémoire un
processus de k unités. Le gestionnaire de la mémoire doit alors parcourir la table de
bits à la recherche de k zéros consécutifs. Cette recherche est lente, ce qui fait qu'en
pratique on utilise rarement les tables de bits.
La figure suivante montre une mémoire divisée en unité d’allocation dont la taille
peut varier de quelques mots à plusieurs kilo-octets. Bit à 0 si l’unité est libre, Bit à 1
si l’unité est occupée
(a) Une partie de la mémoire occupée par 5 processus
(b) Table de bits correspondante
(c) Liste chaînée

3.2.2 - GESTION DE LA MEMOIRE PAR LISTES CHAINEES

Une deuxième méthode pour mémoriser l'occupation de la mémoire consiste à gérer


une liste chaînée des segments libres et occupées, un segment étant un processus ou
un espace libre entre deux processus. Chaque entrée spécifie une zone libre ou un
processus P, son adresse de départ sa longueur et un pointeur sur l'entrée suivante
(figure b). La liste est triée sur les adresses. Ce tri permet de mettre la liste à jour
facilement lorsqu'un processus se termine ou est déplacé sur le disque. Quand on
mémorise les processus et les zones libres dans une liste triée en fonction des
adresses, on peut utiliser plusieurs algorithmes pour allouer de la mémoire aux
nouveaux processus ou aux processus ramenés en mémoire principale : figure (b)

© W. KADRI 42
 ALGORITHME DE LA PREMIERE ZONE LIBRE (FIRST FIT)

Le gestionnaire de mémoire parcourt la liste de segments (toujours à partir du début)


à la recherche de la première zone libre qui peut contenir le processus. Cette zone est
alors scindée en deux : la première contient le processus et la deuxième, l'espace
mémoire inutilisé (sauf si le processus a exactement la même taille que la zone). Cet
algorithme est rapide puisqu'il y a très peu de recherche.

 ALGORITHME DE LA ZONE LIBRE SUIVANTE (NEXT FIT)

C'est une légère variante de l'algorithme précédent. Il mémorise en plus la position


de l'espace libre trouvé. La recherche suivante commencera à partir de cette position
et non à partir du début. Il a été mis en évidence que cet algorithme est moins
performant que le précédent.

 ALGORITHME DU MEILLEUR AJUSTEMENT (BEST FIT)

On recherche la zone libre la plus petite qui convient. On évite ainsi de fractionner
une grande zone dont on pourrait avoir besoin plus tard. Il est plus lent car il
parcourt toute la liste et ce qui est le plus étonnant, c'est qu'il fait perdre plus
d'espace que les deux précédents.

 ALGORITHME DU PLUS GRAND RESIDU (WORST FIT)

Il consiste à toujours prendre la plus grande zone libre disponible pour que la zone
libre restante soit la plus grande possible. La simulation a montré que cette stratégie
ne donne pas de bons résultats. On peut accélérer ces quatre algorithmes en utilisant
les listes séparées pour les processus et les zones libres et de nombreux autres
algorithmes s'appliquent si on suppose connues à l'avance la distribution de taille
des processus et leur durée d'exécution.

3.2.3- GESTION DE LA MEMOIRE PAR SUBDIVISION

© W. KADRI 43
L'allocution par subdivision est un algorithme de gestion de la mémoire qui s'appuie
sur le fait que les ordinateurs utilisent des adresses binaires de manière à accélérer la
fusion de zones libres adjacentes lorsqu'un processus se termine ou est déplacé sur le
disque. Le gestionnaire de mémoire mémorise une liste des blocs libres dont les
tailles sont de 1, 2, 4, 8, 16…octets, jusqu’à la taille maximale de la mémoire

Les algorithmes présentés ci-dessus mémorisent l'occupation de la mémoire


principale pour que le système puisse trouver de la place lorsqu'un processus y est
ramené. Dans certains systèmes, on n'alloue pas à l'avance un espace fixe sur le
disque aux processus qui sont en mémoire. Quand un processus doit être copié sur le
disque, on lui attribue de la place dans l'espace de va-et-vient (swap area) sur le
disque. Les algorithmes de gestion de l'espace de va-et-vient sont identiques à ceux
de gestion de la mémoire principale. La seule différence est que l'espace de va-et-
vient d'un processus est un nombre entier de blocs de disque. Si par exemple les
blocs de disque font 1Ko, on attribue à un processus de 13,5 Ko un espace de va-et-
vient de 14 Ko.

4- LES MECANISMES DE DECOUPAGE DE LA MEMOIRE

La mémoire centrale peut-être découpée de trois façons :


 la pagination: elle consiste à diviser la mémoire en blocs, et les programmes
en pages de longueur fixe.
 la segmentation : les programmes sont découpés en parcelles ayant des
longueurs variables appelées «segments».
 une combinaison de segmentation et de pagination: certaines parties de la
mémoires sont segmentées, les autres sont paginées.

4.1 - LA PAGINATION

L'espace d'adressage virtuel est divisé en petites unités appelées des pages. Les
unités correspondantes de la mémoire physique sont les cases mémoires (page
frames). Les pages et les cases ont toujours la même taille. Les transferts entre la

© W. KADRI 44
mémoire et le disque se font toujours par pages entières. La longueur des pages est
toujours une puissance de 2 ce qui facilite l'obtention de l'adresse physique par
assemblage binaire.

Le mécanisme de gestion qui permet de passer d'une adresse virtuelle à une adresse
physique dans un système de pagination passe par la table des pages. Les propriétés
de la table de pages sont les suivantes :
 Il y a une table des pages pour chaque programme;
 La table des pages contient une entrée pour chaque page virtuelle du
programme;
 Le début de la table des pages est chargé dans un registre : le registre de base
de la table de pages (RBTP);
 Chaque entrée de la table peut contenir :
o des bits de contrôle :
 page présente en mémoire/page absente;
 page modifiée/non modifiée;
 autorisation d'accès en écriture;
 compteur d'utilisation;
o deux adresses :
 position de la page en mémoire secondaire (en général un disque
: unité, face, piste et secteur);
 numéro du bloc de mémoire physique contenant la page, si la
page virtuelle est présente en mémoire.

Le registre de base et le registre de base de la table de pages font partie du contexte


du programme. La mise à jour de la table des pages est assurée par le système.
L'exploitation de cette table pour le calcul de l'adresse physique peut être effectuée
par le système, mais cela consomme une partie du temps CPU disponible. Pour
libérer le système d'exploitation cette gestion, comme nous l’avons précisé
précédemment, peut être confiée à un circuit spécialisé : unité de gestion de la
mémoire (MMU : Memory Management Unit) intercalée entre l'unité centrale et la
mémoire.

Le mécanisme de gestion de la mémoire peut se décomposer de la manière suivante :

1) L'adresse virtuelle est séparée en deux parties :


 numéro de page virtuelle.
 déplacement dans la page : identique dans la page physique;
2) On ajoute le contenu du registre RBTP au numéro de page virtuelle obtenu
lors de l'étape 1. Cela nous donne l'adresse de l'entrée correspondante dans
la table des pages.
3) On teste le bit de présence :
a) La page est présente. Le numéro du bloc physique contenant la page
est chargé dans le registre de base. L'adresse physique est calculée en
assemblant le registre de base au déplacement dans la page obtenu en
1.

© W. KADRI 45
b) La page est absente. Le MMU constate que cette page n'est pas
mappée et provoque un déroutement (trap) : le processeur est restitué
au S.E (la main est donnée à l’OS). Le déroutement est appelé un défaut
de page (page fault). Le S.E repère une case en utilisant un algorithme
de défaut de page, et recopie son contenu sur le disque. Il met à jour la
table des pages et cherche sur disque la page demandée, ensuite, la
place dans la case qui vient d'être libérée, positionne leurs bits et
relance l'instruction déroutée. On est alors ramené au cas 3a

Pour accélérer la phase 3.a il est possible d'utiliser une mémoire associative utilisant
le numéro de page virtuelle comme étiquette et fournissant en sortie le numéro de
bloc physique. Cette mémoire associative ne contient alors que les pages en mémoire.
Si la recherche est infructueuse le système utilise la table des pages.

Une autre fonction de l'unité de gestion de la mémoire consiste à vérifier la cohérence


des attributs d'accès. Chaque tâche possède des attributs : mode utilisateur, mode
superviseur, etc… Il en est de même pour les zones mémoires. On peut avoir :
- Lecture uniquement;
- Superviseur uniquement;
- Zone programme;
- Zone donnée;
- etc…
Si l'accès viole les attributs de la cible, la MMU doit interrompre la requête mémoire
et engendrer une condition d'erreur ou une interruption particulière appelée
exception.

© W. KADRI 46
Exemple

Soit, par exemple des pages de 4Ko avec 64Ko de mémoire virtuelle et 32Ko de
mémoire physique. On a, donc, 16 pages virtuelles et 8 cases. Les transferts entre la
mémoire et le disque se font toujours par pages entières.
Soit l’instruction MOVE R0, 0, l'adresse virtuelle 0 est envoyée au MMU. Ce dernier
constate que cette adresse virtuelle se situe à la page 0 (adresses de 0 à 4095) qui
appartient à la case 2 (8192 à 12887). Le MMU transforme l'adresse en 8192 et place
cette valeur sur le bus. La carte mémoire ne connaît pas l'existence du MMU. Elle
reçoit simplement une demande de lecture de l'adresse 8192. Le MMU a donc mappé
les adresses virtuelles comprises entre 0 et 4096 sur les adresses physiques 8192 à
12357.

Ce mappage au moyen du MMU des 16 pages virtuelles sur n'importe laquelle des
huit cas ne résout pas le problème soulevé par le fait que l'espace d'adressage virtuel
est plus grand que la mémoire physique. Comme on n'a que huit cas physiques, on
ne peut mapper que huit pages virtuelles sur la mémoire physique. Que se passe-t-il
si le programme tente d'utiliser une page non mappée par exemple en effectuant un
MOVE R0, 32780 ? (cette adresse se situe à un déplacement de 12 octets après le
début de la page 8 qui commence à l' adresse 32768.) Le MMU constate que cette
page n'est pas mappée et provoque un déroutement (trap) : le processeur est restitué
au S.E. Le S.E repère une case en utilisant un algorithme de défaut de page, et recopie
son contenu sur le disque. Il met à jour la table des pages et cherche sur disque la
page demandée, ensuite, la place dans la case qui vient d'être libérée, positionne
leurs bits et relance l'instruction déroutée.

4.1.1- MEMOIRE CACHE OU ANTEMEMOIRE

Le concept de mémoire virtuelle paginée peut être vu comme un cache, la mémoire


physique constituant un cache pour la mémoire secondaire. D'une façon générale, on
appelle cache tout dispositif matériel ou logiciel qui stocke dans une zone d'accès
rapide une copie de données en petite quantité choisies parmi des données qui sont
stockées dans une zone d'accès plus lent.

Dans le cas de la pagination, la mémoire primaire est la mémoire physique et la


mémoire secondaire est l'espace sur disque. La mémoire physique ne contient, à un
instant donné, que les seules pages du programme utilisées récemment. Dans le cas
d'un cache-mémoire, la mémoire primaire est une mémoire rapide, la mémoire
secondaire est la mémoire principale de la machine. Le cache-mémoire ne contient, à
un instant donné, que les copies de petits blocs de mots de la mémoire physique
récemment référencés. Il y a cependant une nuance. Pour la pagination le temps
nécessaire au chargement d'une page à partir du disque est long. Ce mécanisme est
géré par le système et le programme en cours perd le contrôle de l'unité centrale.
Pour l'antémémoire la gestion se fait uniquement au niveau du matériel et le
programme en cours conserve la main.

© W. KADRI 47
On utilise pour les caches des mémoires statiques très rapides. La mémoire cache
permet de combler en partie la différence entre les vitesses de l'unité centrale et de la
mémoire. On trouve très souvent deux niveaux de mémoire cache. Le premier niveau
est intégré au processeur et dispose d'un temps d'accès équivalent au cycle de
fonctionnement de celui-ci. Le second niveau est de plus grande taille mais plus lent.
Une mémoire cache intégrée au processeur, ou très proche, est basée sur une
mémoire associative.

Les statistiques ont montré que 80 à 90 % des programmes se trouvent dans des
boucles. C'est pourquoi une mémoire cache peut obtenir un taux de réussite,
probabilité de trouver l'instruction dans le cache, de 70 à 90 %. L'emploi des
mémoires caches est essentiel dans les architectures RISC. Certains processeurs
disposent de deux caches pour les instructions et les données (architecture de
Harvard).

Même en dehors d'une boucle, comme le traitement des instructions est séquentiel on
a intérêt à transférer les instructions par blocs. On appelle un tel bloc une ligne,
équivalente à la page entre mémoire et disque.

La figure suivante illustre le schéma de principe d'une architecture avec


hiérarchisation de la mémoire.

Voici un schéma présentant clairement le mécanisme de traduction des adresses

© W. KADRI 48
Adresses utilisées directement par le coeur du processeur, et qui constituent les
adresses mentionnées dans les programmes et le système d'exploitation.

C’est simplement un déplacement (32 bits) par rapport au début de l’espace


d’adressage du processus.

C’est l’adresse qui sera directement utilisé à l’extérieur du processeur pour la


manipulation de la mémoire (32 ou 36 bits).

4.2 - LA SEGMENTATION

La pagination est une technique qui permet d'implanter un grand espace d'adressage
linéaire dans une mémoire physique limitée. Pour certaines applications, il est plus
commode d'avoir un espace d'adressage à 2 dimensions. L'idéal serait que chaque
processus possède un grand nombre de segments ( par ex 232 )formé chacun d'un
grand nombre d'octets(232). Les premiers segments (par ex les 64 premiers Ko)sont
réservées aux procédures, aux données, à la pile et au tas du programmes en cours
d'exécution. Les autres segments peuvent chacun contenir un fichier pour que les
processus puissent adresser directement leurs fichiers sans avoir à les ouvrir et à
utiliser les primitives d'E/S particulières pour les lire et les écrire.

5 – LES ALGORITHMES DE REMPLACEMENT DE PAGE

A la suite d'un défaut de page, le SE doit retirer une page de la mémoire pour libérer
de la place pour la page manquante. Si la page à retirer a été modifiée depuis son
chargement en mémoire, il faut la réécrire sur le disque. Sinon le disque est déjà à
jour. La page lue remplace simplement la page à supprimer. Cette dernière peut être
choisie au hasard, mais on améliore sensiblement les performances du système si on
choisit une page peu utilisée. Les algorithmes de remplacement de page ont été très
étudiés tant du point de vue théorique que pratique.

5.1 - PAGE OPTIMAL

Le meilleur algorithme de remplacement est facile à décrire mais difficile à mettre en


œuvre. Voici l’algorithme :

Au moment du défaut de page, il existe en mémoire un certain nombre de pages.


Une de ces pages risque d'être référencée très vite, d'autres ne sont référencées que
plus tard. On peut numéroter chaque page avec le nombre d'instructions qui seront
exécutées avant qu'elle ne soit référencée. L'algorithme de remplacement de page
optimal consiste à retirer la page qui comporte le plus haut numéro. On repousse,
ainsi, le défaut de page suivant le plus tard possible. Malheureusement, cet
algorithme est irréalisable car le SE ne peut pas connaître à l'avance le moment où les
différentes pages seront référencées. On peut néanmoins implémenter cet algorithme
en exécutant le programme sur un simulateur qui mémorise toutes les références aux
© W. KADRI 49
pages lors d'une première exécution et utilise ces informations lors d'une deuxième
exécution.

5.2 - PAGE NON RECEMMENT UTILISEE (NRU)

Les ordinateurs associent à chaque page deux bits d'informations sur les pages
utilisées. Le premier bit, R ou bit de référence, est positionné par le matériel à chaque
lecture ou écriture de la page .Le deuxième bit, M ou de modification est positionné
quand on écrit dans une page (stockage d’un byte dans cet page). Ces deux bits R et
M permettent de construire l'algorithme de pagination suivant :

Au lancement d'un processus, le S.E. met à 0 les bits R et M de toutes ses pages.
Périodiquement (sur chaque interruption d’horloge), le bit R est remis à 0 pour
différencier les pages qui n'ont pas été récemment référencées des autres. Lorsqu'un
défaut de pages se produit le SE parcourt toutes les pages et les repartit dans les
quatre classes suivantes en fonction des différentes valeurs de bits R et M.
 Classe 0 : Non référencée, non modifiée (R=0 , M=0)
 Classe 1 : Non référencée, modifiée (R=0 , M=1)
 Classe 2 : Référencée, non modifiée (R=1 , M=0)
 Classe 3 : Référencée, modifiée (R=1 , M=1)

L’interruption d’horloge n’affecte pas M puisqu’il est utilisé pour savoir si la page
sera modifiée (réécrite sur disque).

L'algorithme de la page non récemment utilisée ou NRU (Not Recently Used) retire
une page au hasard de la catégorie non vide qui a le plus petit numéro (0,1,2,3).
L'algorithme NRU est facile à comprendre, relativement efficace et fournit des
performances qui sont suffisantes même si elles ne sont pas optimales.

5.3 - PREMIER ENTRE, PREMIER SORTI (FIRST-IN, FIRST-OUT: FIFO)


 FIFO Simple :

Le SE mémorise une liste de toutes les pages en mémoires, la première page étant la
plus ancienne et la dernière, la plus récente. Lorsqu'il se produit un défaut de pages,
on retire la première page de la liste et on place la nouvelle à la fin de cette liste. Cet
algorithme, présente l'inconvénient de pouvoir retirer une page ancienne mais très
utilisée.
 FIFO Amélioré :

Une modification de cet algorithme consiste à examiner les bits R et M de la page la


plus ancienne. Si cette page appartient à la catégorie 0 (non référencée, non modifiée)
elle est supprimée ; sinon on teste la page un peu moins ancienne et ainsi de suite. S'il
n'y pas de page dans la catégorie 0, on applique cet algorithme aux catégories 1, 2
puis 3.

 FIFO 2ème Chance :


Une autre alternative de cet algorithme est la seconde chance. On recherche par la
méthode précédente la page la plus ancienne. Si R=0, la page est immédiatement
© W. KADRI 50
prise, si R=1 il est mis à 0 et la page est placée en queue de liste comme si elle vient
d’arriver en mémoire.

5.4 - LA MOINS RECEMMENT UTILISEE (LRU)

Une solution consiste à remplacer la page la moins récemment utilisée (LRU : Least
Recently Used). C'est le rôle du compteur associé à chaque entrée de la table des
pages. Il indique la plus récente référence à la page. D'autre part, si la page a été
modifiée il faut la sauvegarder en mémoire secondaire avant de libérer
l'emplacement physique.

Une bonne approximation de l'algorithme optimal se fonde sur l'observation


suivante : les pages les plus référencées au cours des dernières instructions seront
probablement très utilisées au cours des prochaines instructions. De même, les pages
qui n'ont pas été référencées pendant un long moment ne seront probablement pas
demandés pendant un certain temps. Cette observation suggère l'algorithme suivant
: lorsqu'il se produit un défaut de page, il faut supprimer la page qui est restée
inutilisée pendant le plus de temps.

Cette stratégie est celle de la page la moins récemment utilisée ou pagination LRU
(least recently used) L'algorithme LRU est théoriquement réalisable mais il est très
coûteux. Il faut en effet mémoriser une liste chaînée de toutes les pages en mémoire.
La page la plus utilisée étant en tête et la moins utilisée en queue de liste. La
difficulté naît du fait que cette liste doit être mise à jour chaque fois que la mémoire
est adressée.

Il y d’autres façons de l’implémenter :


 1ère méthode utilisation d’un compteur hard: cette méthode consiste à utiliser
un registre de 64 bits (compteur) qui est automatiquement incrémenté après
chaque instruction. A chaque entrée de la table des pages on associe un
champs de la taille du compteur. Après chaque référence de mémoire, la
valeurs du compteur est stockée dans l’entrée de la page qui vient d’être
référencée. Quand un défaut de page se produit, l’SE examine tous les
compteurs de la table des pages pour chercher le plus petit. C’est la page la
moins utilisée.
 2ème méthode utilisation d’une matrice: pour un machine à n pages physique,
le LRU maintient une matrice n*n bits initialement à 0. quand la page k est
référencée, le hardware met la ligne k à 1 et la colonne k à 0. A cet instant, la
ligne dont la valeur binaire est la plus petite est la moins utilisée récemment.
 3ème méthode ; simulation en software (NFU not frequently used): cet
algorithme nécessite un compteur soft associé à chaque page. Initialement nul.
A chaque interruption d’horloge, l’SE parcourt toutes les pages en mémoire.
Pour chacune d’elle le bit R qui est soit 0 soit 1 est ajouté au compteur. Quand
un défaut de page se produit, la page de plus petite valeur du compteur est
choisie.

© W. KADRI 51
6- CONCEPTION DES SYSTEMES PAGINES

Le principe de la pagination et les algorithme de remplacement de page ne suffisent


pas à concevoir un système qui fonctionne correctement. Nous allons examiner
d’autres résultats non ignorés par les concepteurs des systèmes d’exploitation.

6.1- Page à la demande

Dans ce modèle, les processus sont lancés sans qu’aucune de leurs pages ne soit en
mémoire. Dès que le processeur essaye d’exécuter le premier Working-Set, il se
produit un défaut de page. Le système amène la page qui contient l’instruction.
D’autres défaut de pages ramèneront les Data et la Pile du processus. Au bout d’un
moment, le processus dispose de la majorité de ces pages et s’exécute sans défaut de
page fréquent. Ce mécanisme est la stratégie de la page à la demande. Cependant, un
programme qui génère beaucoup de défaut de pages provoque l’écroulement du
système.

6.2- Préchargement (prepaging)

La solution est d’affecter à chaque processus un certain nombre de pages toutes


présentes en mémoire constituant son Working-Set. A chaque fois qu’un processus
est chargé ou déchargé entre la mémoire et le disque, tout son Working-Set est
swappé out ou in. En système à temps partagé, l’ensemble des Working-Set constitue
le Balance-Set. Quand un processus est en mémoire son Working-Set est dans le
Balance-Set. Si le processus n’est plus en mémoire, son Working-Set n’est plus dans
le Balance-Set. Toutefois, si la taille du Balance-Set est supérieure à la taille de la
mémoire disponible, il se produit un écroulement du système.

6.3- Allocation locale et allocation globale :


L’allocation locale se passe à l’intérieur du Working-Set. L’allocation globale se passe
à l’intérieur de Balance-Set. L’utilisation des algorithmes de remplacement des pages
doivent se limiter aux différents ensembles. L’allocation locale revient à affecter à
chaque processus une taille mémoire fixe. L’allocation globale alloue
dynamiquement des pages aux processus.

© W. KADRI 52
Quatrième Chapitre
GESTION DES ENTREES-SORTIES

1- INTRODUCTION

Le contrôle des périphériques d’E/S de l’ordinateur est une des fonctions


primordiales d’un OS. Le système OS doit envoyer les commandes aux
périphériques, intercepter les interruptions et traiter les erreurs. Il doit aussi fournir
une interface simple et facile d’emploi. Le code des E/S représente une part
importante de l’ensemble du système. Ce chapitre montre comment un OS gère ces
E/S.

Ce qu’il appartient de savoir et de bien maitriser est le cheminement d’une E/S


depuis une commande shell ou un programme utilisateur jusqu’à sa totale exécution.
La figure 4.1 exprime se schéma.

Un utilisateur lance une commande shell (a) ou l’exécution d’un fichier contenant
une primitive d’E/S système (b).

Un appel superviseur va faire passer l’état du mode utilisateur (user) au mode noyau
pour permettre l’exécution de la primitive (c). pour une question de protection
système les primitives qui se chargent d’exécuter les E/S doivent s’exécuter en mode
noyau (Kernel).

Le système se charge maintenant d’entreprendre l’E/S, il dispose d’une table


identique à la table des interruptions qu’on appelle table des primitives systèmes.
Cette table identifie chaque primitive par un numéro qui est son indice dans la table.
L’interpréteur de commande ou le compilateur traduit le nom de la commande
d’E/S par son indice dans la table et envoie cet indice au système. La commande CD
(a) peut avoir un indice K.

Le système identifie l’appel système dans la table grâce à K. il va dans la table à


l’indice K et extrait l’adresse de la routine qui va prendre en compte l’E/S. Il donne la
main à cette routine qui débute son exécution, elle va chercher ses paramètres soit
dans les registres du CPU soit dans la pile. Effectivement le programmeur doit placer

© W. KADRI 53
ces paramètres avant d’entamer l’appel. Le compilateur ou le shell se charge, dans les
cas précédents, à placer ces paramètres au bon endroit.

(a)

(b)

Supposons que l’on dispose d’une primitive système qui se charge d’imprimer à
l’écran un caractère passé en paramètre. La documentation système indique que la
primitive sur un CPU (décrit au chapitre translation) exige que le caractère à
imprimer doit se trouver dans le registre R1. Le système impose que pour réaliser
l’appel superviseur on doit placer le numéro K de la primitive dans le registre R0 et

© W. KADRI 54
provoquer l’appel superviseur par l’interruption INT 21h. (dans le cas de notre CPU (
TRAP # X21). Ceci se résume selon l’assembleur de notre machine par :

LL R1 , #’caractère à imprimer’
LL RO, #K
TRAP #X21.

USER

KERNEL
(c)
La main est donnée, par la trappe, au système qui passe directement à RO, il trouve
l’indice K, il passe à la table des primitives systèmes à l’entrée K et extrait la
primitive d’affichage du caractère à l’écran. Il initialise cette routine qui va
directement à R1 pour prendre son contenu et l’imprimer à l’écran. L’implémentation
de la trappe (int 21h) système est implicite au shell et aux librairies systèmes
associées aux langages de programmation. Le schéma (d) montre ce cheminement.

(d)

La routine se charge, à ce stade, d’initialiser le pilote(driver) charger d’entreprendre


l’E/S.
Le pilote est une tâche système s’exécutant en temps réel par le scheduling.

Principes des E/S matérielles :


Un organe d’E/S est un dispositif capable de transférer de l’information entre
processeur ou la mémoire et un support d’information externe. Ce transfert est
commandé par le processeur central. Une instruction spéciale du processeur permet
de transférer l’information entre le support externe et un registre du processeur qui
devient alors occupé pendant toute la durée du transfert.

Un souci de meilleur utilisation du processeur a conduit à accroître l’autonomie des


organes d’E/S et à leur confier des fonctions de plus en plus complexes, le

© W. KADRI 55
processeur central ne gardant que l’initiative du lancement et du contrôle des
opérations
PERIPHERIQUE
C’est un organe capable de transformer de l’information depuis ou vers un support
externe. Le système [contrôleur, périphérique] définit une interface capable d’un
certain nombre de fonctions. Cet interface :
- accepte des commandes
- exécute des fonctions
- signale des erreurs

On s’intéresse donc à la programmation des périphériques et non à leurs structures


internes. Les périphériques se répartissent en deux classes :
- périphériques blocs : mémorise l’information dans des blocs de
mémoire de taille fixe. Ils permettent de lire et d’écrire un bloc
indépendamment de tous les autres. Le disque en et un exemple.
- périphériques caractères : ils acceptent un flot de caractères sans se
munir d’une structure quelconque en bloc. Ils ne peuvent être adressés
et ne possèdent pas de fonctions de recherche. Les terminaux, les
imprimantes, les interfaces réseaux sont des exemples.

CONTROLEURS

C’est un dispositif de commandes, souvent des cartes électroniques insérées dans


l’ordinateur, adapté à un type donné de périphérique. Son autonomie est limitée à
des opérations très élémentaires. Le principal intérêt de séparer le contrôleur du
périphérique est de pouvoir connecter plusieurs périphériques de même type à un
même contrôleur.

Le partage de fonctions entre le contrôleur et le périphérique dépend du type de


périphérique ; schématiquement, les fonctions logiques (enchaînement,
synchronisation des opérations, envoi de signaux de fin ou début d’incident) sont
confiées au contrôleur. Les fonctions physiques (transfert proprement dit) sont
confiées au périphérique. Le système OS ne communique pas avec le périphérique
mais avec le contrôleur.

CANAUX

Un canal ou unité d’échange est un processeur spécialisé dans les opérations d’E/S. il
ne peut être lancé que par le processeur central et ne possède pas d’interruptions
mais peut interrompre le processeur central. Son répertoire d’instructions lui permet
d’activer les contrôleurs et les périphériques qui lui sont connectés. Sur les mini-
ordinateurs et les micro-ordinateurs on trouve une forme simplifiée de canal appelée
« ADM »
- Acces Direct Memory (ADM): Pour expliquer le fonctionnement du DMA,
examinons la lecture du disque lorsque le DMA n’est pas utilisé. Le contrôleur lit un
bloc (un ou plusieurs secteurs) bit par bit jusqu’à ce qu’il soit entièrement dans le
tampon du contrôleur. Puis il effectue un contrôle pour vérifier les erreurs. Le
contrôle ne peut avoir lieu que si le bloc a été entièrement lu. Le contrôleur génère

© W. KADRI 56
une interruption. L’OS peut lire le tampon du contrôleur et le recopier en mémoire.
Cette lecture peut se faire au moyen d’une boucle qui lit à chaque itération un octet
ou un mot du tampon. Elle consomme beaucoup de temps.
Le DMA a été installé pour libérer le processeur de ce travail de bas niveau. Le
processeur donne au contrôleur l’adresse des blocs sur le disque, l’adresse mémoire
où ils seront transmis et le nombre d’octets à transmettre.

Les interblocages

L’accès exclusif à une ressource conduit à de sérieux problèmes. Supposons qu’un


ordinateur possède un dérouleur de bande et une table traçante et que tous les deux
ne possèdent pas de spool. Un processus A demande le dérouleur de bande et un
processus B la table traçante. Les deux accès sont accordés. Ensuite A demande la
table traçante sans libérer le dérouleur et B demande le dérouleur sans libérer la
table. Aucune requête n’est accordée et les deux processus restent en attente de
ressources (endormis). Ils resteront ainsi indéfiniment. Cette situation est appelée
‘Interblocage » (Deadlock).

On qualifie de ressources tout objet pouvant être alloué à un processus. Elle peut être
un périphérique, un processeur, une zone mémoire, un fichier etc..
L’utilisation d’une ressource produit les 3 évènements:
1- Demande de la ressource
2- Utilisation de la ressource
3- Libération de la ressource

Il faut réunir 4 conditions simultanément pour provoquer un interblocage :


1- l’exclusion mutuelle : chaque ressource est soit attribuée à un seul processus
soit disponible.
2- La détection et l’attente : les processus qui détiennent des ressources
précédemment obtenues peuvent en demander des nouvelles.
3- Pas de réquisition : les ressources obtenues par un processus ne peuvent lui
être retirées contre son gré. Elles doivent être implicitement libérées par le
processus qui les détient.
4- L’attente circulaire : il doit y avoir un cycle d’au moins deux processus chacun
d’entre eux attendant une ressource détenue par un autre processus du cycle.

EVITER LES INTERBLOCAGE :

Cette manière consiste à demander des informations supplémentaires sur la façon


dont les ressources vont être requises (l’ordre d’acquisition des ressources). Le
modèle le plus simple et le plus utile exige que chaque processus déclare à l’avance le
nombre maximal de ressources de chaque type dont il a besoin.

ETAT SUR :

Un état est sûr si le système peut allouer des ressources à chaque processus (jusqu’à
son maximum) dans un certain ordre évitant l’interblocage.

© W. KADRI 57
Un système est dans un état sûr s’il existe une séquence saine. Un séquence de
processus <P1, P2,…Pn>est saine si pour chaque Pi, les requêtes de Pi peuvent être
satisfaite par les ressources disponibles plus les ressources détenues par tous les Pj
avec j<i.

GRAPHE D’ALLOCATION :

Avec une seule instance pour chaque type de ressource, on peut éviter les
interblocages en utilisant le graphe des ressources. On ajoute un arc au graphe que si
cet arc ne produit pas de cycle.

ALGORITHME DU BANQUIER :

L’algorithme du banquier s’applique à plusieurs instances. Il s’inspire de la manière


dont un banquier accorde des crédits à ses clients :
Soit n le nombre de processus et m le type de ressources
- Available : indique le nombre de ressources disponibles Available[j]= k,
il existe k instances de type Rj.
- Max : matrice n*m définissant la demande max de chaque processus.
Max(i,j)=k  Pi peut demander au plus k instances de type Rj
- Allocation : ressources courantes. Allocation (i,j)=k  on a alloué k
instances Rj à Pi
- Need : le besoin en ressources. Need(i,j)=Max(i,j)-Allocation(i,j)

ALGORITHME DE DETECTION D’ETAT SUR

1- soient Work et Finish des vecteurs de longueurs m et n. initialement


Work=Available et Finish(i)=False pour i=1..n
2- trouver i tq
a- Finish(i)=false
b- Needi <= Work
Si i n’existe pas alors aller à 4
3- Work=Work + Allocation
Finish=true
Aller à 2
4- Si Finish(i)=true i alors le système est dans un état sûr
5- Répéter 2 jusqu’à Finish(i)=true i

ALGORITHME DE DETERMINATION D’ETAT SUR

1- Soit Work(m) et Finish(n) deux vecteurs


Initialement : Work= Available
Finish[i]= false pour i=1..n
2- Trouver i tel que
- Finish[i]=false
- Need i <= Work

© W. KADRI 58
Si i n’existe pas aller à 4
3- Work= Work + Allocation
Finish(i)=true
Aller à 2
4- Si Finish[i]=true pour i=1..n alors le système est dans un état sûr

ALGORITHME DE REQUETES DES RESSOURCES


Soit Requesti= vecteur des requêtes de Pi
Si Requesti(j)=K  Pi désire K instances de Rj. Quand Pi requiert des ressources on
effectue :
1- si Requesti  Needi aller à 2 sinon situation d’erreur (le processus a excédé sa
demande maximale)
2- si Requesti  available aller à 3 sinon Pi doit attendre (les ressources ne sont
pas disponibles)
3- on suppose que le système a alloué les ressources demandées par Pi
Available= Available – Requesti
Allocation = Allocationi + Requesti
Needi = Needi – Requesti

Si l’état d’allocation est sûr la transaction est terminée et on alloue à Pi ses ressources.
Si le nouvel état n’est pas sûr, Pi doit attendre et l’ancien état est restauré.
Exemple :
Soit un système avec un 5 processus P0, P1, P2, P3, P4 et 3 types de ressources

Allocation Max Available


A B C A B C A B C
P0 0 1 0 7 5 3 3 3 2
P1 2 0 0 3 2 2
P2 0 1 0 9 0 2
P3 0 1 0 2 2 2
P4 0 1 0 3 3 3

Need= Max – Allocation

A B C
P0 7 4 3
P1 1 2 2
P2 6 0 0
P3 0 1 1
P4 4 3 1

1- Le système est couramment dans un état sûr. Puisque <P1, P3, P4, P2, P0> est
une séquence saine
2- Supposons que P1 demande 1 instance de A et 2 instances de C.
Donc Request1= (1, 0, 2) . Pour décider si la requête est accordée :
1- Si Request1  Available  (1,0,2)  (3,3,2) ce qui est vrai
2- Nous arrivons à l’état :
Allocation Need Available
A B C A B C A B C

© W. KADRI 59
P0 0 1 0 7 4 3 2 3 0
P1 3 0 2 0 2 0
P2 3 0 2 6 0 0
P3 2 1 1 0 1 1
P4 0 0 2 4 3 1

Est-il sûr  algorithme de l’état sûr <P1, P3, P4, P0, P2> est saine dons
Request accordée. Cependant Request4= (3,3,0) de P4 ne peut être accordée.
Request4 = (3,3,0) Available = (2,3,0) non
Request0 = (0,2,0) ne peut être satisfaite puisque l’état est non sûr

DETECTER LES INTERBLOCAGES :


Si un système n’utilise pas d’algorithme pour prévenir ou pour éviter les
interblocages, le système doit fournir alors :
- un algorithme qui examine l’état du système pour déterminer s’il s’est
produit un interblocage.
- Un algorithme pour corriger l’interblocage.

1- Une seule instance de ressource


Dans la cas de l’instance unique, on applique l’algorithme « graphe d’attente ». on
obtient ce graphe à partir du graphe d’allocation en supprimant les nœuds de types
ressources et en rabattant les arcs adéquats. Un arc de Pi vers Pj dans un graphe
d’attente implique que Pi attend une ressource occupée par Pj. Un arc PiPj existe
dans le graphe d’attente si il existe PiRq et RqPj dans le graphe d’allocation. Il y
a interblocage, si le graphe d’attente contient un circuit.

Exemple :
P5

P5
R3
R4
R1
P1 P2 P3
P2
P1 P3

P4

P4 R5
R2
Graphe d’attente
Graphe d’allocation

Pour détecter les interblocages, le système doit assurer la maintenance du graphe


d’attente en appelant un algorithme de recherche de circuit dans un graphe.

© W. KADRI 60
2- Instance multiple de ressources
Exemple :

Allocation Request Available


A B C A B C A B C
P0 0 1 0 0 0 0 0 0 0
P1 2 0 0 2 0 2
P2 3 0 3 0 0 0
P3 2 1 1 1 0 0
P4 0 0 2 0 0 2

<P0,P2,P3,P1,P4>  Finish[i]=true pour i=0..4


Supposons que P2 effectue une requête pour C request devient alors :

A B C
P0 0 0 0
P1 2 0 2
P2 0 0 1
P3 1 0 0
P4 0 0 2

Le système en situation d’iterblocage pas de séquence tant que Finish=true

CORRIGER LES INTERBLOCAGES :

1- informer l’opérateur (manager) qu’il s’est produit un interblocage


2- le système corrige automatiquement l’interblocage
Il existe deux opérations pour défaire un interblocage :
 arrêter un ou plusieurs processus afin de rompre l’attente
 réquisitionner des ressources d’un ou de plusieurs processus en
interblocage.

Le disque virtuel
L’information sur disque est référencée par une adresse en plusieurs parties : le
n°d’unité, la piste et le secteur. Toutes les pistes d’une unité auxquelles on accède
sans déplacement des têtes constituent un cylindre. Dans une piste les informations
sont stockées en secteur. Ce dernier étant l’information la plus petite pouvant être lue
ou écrite sur disque.

Pour accéder à un secteur, il faut spécifier la face, la piste et le secteur. 3 paramètres


sont importants :
- temps de positionnement
- temps de latence
- temps de transfert
Pour un disque de s secteurs par piste et de p pistes par cylindre, on peut donner une
adresse disque de cylindre i, de face j et de secteur k par : b= k+s(j+i*p)

© W. KADRI 61
Les algorithmes du Scheduling du disque :
Il est important que le service du disque soit aussi rapide que possible. l’OS peut
améliorer le temps de service en schedulant convenablement les requêtes d’accès au
disque.

1- FCFS :
Cet algorithme est facile à programmer et intrinsèquement juste. Cependant, il ne
peut fournir le même service
Exemple : soit une suite de piste
53, 98, 183, 37, 122, 14, 124, 65, 67

0 14 37 53 65 67 98 122 124 183 199

Inconvénient : déplacement du bras

2- SSTF: Shortest Seek Time First


Il semble raisonnable de servir ensemble toutes les requêtes proches de la position
courante de la tête. L’algorithme sélectionne la requête minimale à partir de la
position courante (distance minimale).
0 14 37 53 65 67 98 122 124 183 199

Inconvénient : il produit la famine de certaines requêtes et n’est pas optimal

© W. KADRI 62
3- SCAN
Cet algorithme fait le scan du disque (balayage) et traite les requête. Il faut connaître
la direction du montant.

0 14 37 53 65 67 98 122 124 183 199

Cet algorithme est appelé parfois l’ascenseur

4- C-SCAN
C’est le SCAN circulaire de la piste 0 dernière et au lieu de faire demi-tour, on revient
à la piste 0.

0 14 37 53 65 67 98 122 124 183 199

5- LOOK
Dans la pratique, le Scan et le C-Scan ne sont pas implémentés de cette manière. En
générale, la tête est seulement déplacée jusqu’à la dernière requête dans cette
direction. Dès qu’il n’existe aucune requête dans la direction courante le mouvement
de la tête est inversé. La version de Scan est Look.
0 14 37 53 65 67 98 122 124 183 199

C-LOOK
C’est le correspondant à C-Scan

0 14 37 53 65 67 98 122 124 183 199

© W. KADRI 63

Вам также может понравиться