Vous êtes sur la page 1sur 37

Brevet de technicien supérieur (BTS2)-Ouarzazate-

CH I : INTRODUCTION AUX SYSTEMES


D’EXPLOITATIONS
1) Introduction :

Un système d'exploitation est un programme qui doit permettre aux utilisateurs d'utiliser les
fonctionnalités d'un ordinateur. Mais il doit aussi aider le programmeur à développer des logiciels de la
façon la plus efficace possible. Un système d'exploitation est mis en route dès qu'on met en marche
l'ordinateur. Dans les grosses machines, il est toujours en exécution. Le système constitue donc une
interface entre l'utilisateur et la machine physique.
2) Définition de système d’exploitation :
C’est un logiciel qui a pour objectif de libérer l'utilisateur d'un ordinateur de la complexité (et la
redondance) de la programmation du matériel.
Le S.E doit :
 contrôler l’exécution des applications :
 Céder le contrôle aux programmes usagers et le reprendre correctement.
 Dire à l’UCT (processeur) quand exécuter tel programme
 Masque les détails du matériel aux applications (Le SE doit donc tenir compte de ces détails).
 Optimiser l`utilisation des ressources pour maximiser la performance du système.

Les couches d'un système informatique.


3) Les fonctions d'un système d'exploitation :

1
Brevet de technicien supérieur (BTS2)-Ouarzazate-
Les systèmes d'exploitation modernes sont constitués de centaines de milliers, voire de millions de
lignes de code et requièrent une grande quantité d'homme-années de travail. Ils ont comme fonctions
principales :
 Chargement et lancement des programmes.
 Gestion des processeurs, de la mémoire, des périphériques.
 Gestion des processus (programmes en cours d'exécution) et des fichiers.
 Protection contre les erreurs et la détection des erreurs, etc.
3.1) Gestion de l’UCT : gestion d’un processus
Un processus est activé par l’intermédiaire d’un agent appelé processeur, c’est l’unité centrale de
traitement (UCT), qui exécute le programme associé. Un processeur est un composant électronique
capable d’effectué des traitements sur tout ensemble de données. Nous disons qu’un processeur exécute
un processus ou qu’un processus est exécuté sur un processeur. Un processus est un programme qui
s'exécute, ainsi que ses données, sa pile, son compteur ordinal, son pointeur de pile et les autres contenus
de registres nécessaires à son exécution.
Attention : ne pas confondre un processus (aspect dynamique, exécution qui peut être
suspendue, puis reprise), avec le texte d'un programme exécutable (aspect statique).
3.2) Gestion des Fichiers :
Un fichier est vu comme une suite d'articles ou d'enregistrements logiques d'un type donné qui ne
peuvent être manipulés qu'au travers d'opérations spécifiques. L'utilisateur n'est pas concerné par
l'implantation des enregistrements, ni par la façon dont sont réalisées les opérations. Généralement, elles
sont traduites par le SE en opérations élémentaires sur les mémoires. On dispose généralement des
opérations suivantes :
 fichiers : créer, ouvrir, fermer, détruire, pointer au début, renommer, copier dans un autre fichier,
éditer le contenu.
 articles : lire, écrire, modifier, insérer, détruire, retrouver.
Un système de gestion de fichiers (SGF) est l'entité regroupant les fichiers mémorisés sur disque. Il
contient les données des fichiers et un ensemble d'informations techniques.
Le système de gestion de fichiers mémorise les fichiers dans des répertoires qui sont eux-mêmes des
fichiers. Un répertoire contient un certain nombre d'entrées (par exemple : nom du fichier, type du fichier,
taille du fichier, propriétaire, protection, date de création, date de dernière modification liste des blocs du
disque utilisé...), une par fichier.
3.3) Gestion de la mémoire :
Pour pouvoir utiliser un ordinateur en multiprogrammation, le SE charge plusieurs processus en
mémoire centrale (MC). La façon la plus simple consiste à affecter à chaque processus un ensemble
d'adresses contiguës (voisines).

2
Brevet de technicien supérieur (BTS2)-Ouarzazate-
Quand le nombre de tâches devient élevé, pour satisfaire au principe d'équitablement et pour
minimiser le temps de réponse des processus, il faut pouvoir simuler la présence simultanée en MC de
tous les processus. D'où la technique de "va et vient" ou recouvrement (swapping), qui consiste à stocker
temporairement sur disque l'image d'un processus, afin de libérer de la place en MC pour d'autres
processus.
D'autre part, la taille d'un processus peut éventuellement dépasser la taille de la mémoire disponible,
même si l'on enlève tous les autres processus. L'utilisation de pages (mécanisme de pagination) ou de
segments (mécanisme de segmentation) permet au système de conserver en MC les parties utilisées des
processus et de stocker, si nécessaire, le reste sur disque.
Le rôle du gestionnaire de la mémoire est de connaître les parties libres et occupées, d'allouer de la
mémoire aux processus qui en ont besoin, de récupérer de la mémoire à la fin de l'exécution d'un
processus et de traiter le recouvrement entre le disque et la mémoire centrale, lorsqu'elle ne peut pas
contenir tous les processus actifs.
3.4) Gestion des E/S:
Leur gestion est une des fonctions principales du système d'exploitation. Il doit en simplifier
l'utilisation, transmettre les commandes, traiter les erreurs, ...
Cette partie est en général sous-évaluée dans les systèmes existants. En règle général, le système
d'exploitation ne gère pas le périphérique directement, mais passe par les contrôleurs de périphérique, s'ils
en ont, qui leur sont propres (contrôleur de disque, d'impression, d'affichage ou carte vidéo ...)
Tous ces contrôleurs facilitent grandement la tâche du système. Sans la carte vidéo, le système
devrait gérer directement les faisceaux de l'écran, régler la résolution "à la main", ...
L'intérêt du multitâche est ici : une fois la commande acceptée par le contrôleur, le processeur peut
passer à d'autres occupations, jusqu'à la fin de l'opération, qui lui est signalée par une interruption qui
réveille éventuellement le processus et lui fait tester le résultat. Pour communiquer avec ces contrôleurs,
le système envoie et reçoit des données au travers de ports d'E/S, au moyen d'instructions spécifiques du
processeur qui permettent la re-direction des données issues de l'UC, non vers la mémoire, mais vers un
périphérique (solution INTEL); ou bien un accès mémoire à une adresse réservée particulière est
interprétée comme demande d'accès à un périphérique (solution Motorola).
Trois solutions sont utilisées pour faire communiquer l'UC et les périphériques :
 Contrôleurs :
Chaque périphérique est connecté à l'ordinateur par l'intermédiaire d'une carte électronique appelée
interface ou adaptateur ou contrôleur de périphérique, qui transforme les signaux du périphérique en
signaux adaptés à l'UC et vice-versa. Un contrôleur peut gérer un ou plusieurs périphériques. Le SE
communique donc avec le contrôleur et non avec le périphérique lui-même.
Exemples de systèmes d'exploitation :

3
Brevet de technicien supérieur (BTS2)-Ouarzazate-
Il y a plusieurs types de systèmes d'exploitation actuellement :
- MS-DOS, Windows
- OS/2, Mac-OS
- Unix (AIX, Xenix, Ultrix, Solaris, etc.)
- Linux ( red hat, mandrak …)
4) évolution des système d’exploitations :
Les premiers systèmes informatiques (1945-1955) :
Caractéristiques :
- Du matériel uniquement.
- Pas de système d’exploitation
- Système mono-usager
Traitement par lots : 1955-1965 :
Les machines étaient construites au moyen de transistors et dotées d'unités de bandes magnétiques.
Elles étaient plus fiables mais toujours énormes (enfermées dans des salles climatisées). Les programmes
étaient écrits en Fortran ou en assembleur sur des cartes perforées. Le mode de fonctionnement
était le traitement par lots qui consiste à :
- Transférer les travaux sur une bande magnétique
- Monter la bande sur le lecteur de bandes
- Charger en mémoire un programme spécial (système d'exploitation) qui lit puis exécute
les travaux l’un après l’autre on parle donc d’une exécution ou traitement par lots. Les résultats sont
récupérés sur une autre bande, à la fin de l'exécution de tout le lot.
- Imprimer les résultats.
Ce mode d'exploitation nécessitait deux machines dont la plus puissante était réservée aux calculs et
l'autre, moins chère, s'occupait des périphériques lents. Le problème est que le processeur restait inutilisé
pendant les opérations d'entrée et sortie (E/S), comme on le voit sur la figure ci-dessous. Le temps
d'attente des résultats était trop long et en plus il n'y avait pas d'interaction avec l'utilisateur.

4
Brevet de technicien supérieur (BTS2)-Ouarzazate-

Temps de processeur
inexploité par le système

Multiprogrammation : 1965-1980
Dans ce système La mémoire est organisée en un ensemble de partitions. Chaque partition peut
contenir au plus un travail. Le système d'exploitation réside aussi dans une partition.

Le système d’exploitation conserve en mémoire plusieurs travaux et gère le partage du processeur


entre les différents travaux chargés en mémoire (la multiprogrammation).
Le processeur est alloué à un travail jusqu'à ce qu'il demande une E/S (demande d’une lecture de
fichier dans un périphérique, demande d’imprimer un fichier…),. Lorsqu'un travail demande une E/S,en
attendant de la fin d'une E/S, le processeur est alloué à un autre travail en mémoire (le suivant). A la fin
d'une E/S, une interruption se produit et le système d'exploitation reprend le contrôle pour traiter
l'interruption et lancer ou poursuivre l'exécution d'un travail. Dès qu'un travail se termine, le système

5
Brevet de technicien supérieur (BTS2)-Ouarzazate-
d'exploitation peut lancer le chargement, à partir du disque d'un nouveau travail dans la partition qui vient
de se libérer.
Exemple :
Considérons les travaux A, B et C en mémoire, qui sont montrés sur la figure ci-dessous.

exécuti
on

L'exécution de A est entamée en premier puis lorsqu'il demande une Entée/Sortie (E/S), le processeur
commute sur B. A la fin de l'E/S demandée par A, le processeur suspend l'exécution de B pour commuter
sur A. On suppose qu'A est prioritaire. Après un certain temps de calcul, A demande de nouveau une E/S
; ce qui provoque la commutation du processeur sur B. Durant l'exécution de l'E/S de A, le travail B
demande une E/S. Il se met donc en attente car le périphérique est occupé. Le processeur commute alors
sur le travail C. Lorsque l'exécution de l'E/S demandée par A s'est terminée, le processeur commute sur A
et le traitement de l - 6 -a demande d'E/S du travail B est entamé par le périphérique d'E/S.
Multiprogrammation et partage de temps : 1965-1980
Le désir d'un temps de réponse plus rapide et d'interactivité de l'exploitation a introduit la technique
de partage de temps (systèmes temps partagé ou Multi-Utilisateurs) : plusieurs utilisateurs peuvent se
connecter à la machine par l'intermédiaire de leurs terminaux et travailler en même temps. Le processeur
est alloué, à tour de rôle, pendant un certain temps à chacun des travaux en attente d'exécution. Au bout
de ce temps (même si le travail en cours ne s'est pas terminé) son exécution est suspendue. Le processeur
est alloué à un autre travail. Si plusieurs utilisateurs lancent à partir de leurs terminaux leurs programmes
simultanément, ce mode d'exploitation donne l'impression que les programmes s'exécutent en parallèle.

6
Brevet de technicien supérieur (BTS2)-Ouarzazate-
Le cas de trois travaux A, B et C est montré sur la figure ci-dessous. Les temps de réponse pour chaque
utilisateur sont acceptables.

exécution

Les systèmes actuels :


Exploitation en réseau
Les réseaux d'ordinateurs personnels qui fonctionnent sous des systèmes d'exploitation en réseau
permettent de se connecter sur une machine distante et de transférer des fichiers d'une machine à une
autre. Ces systèmes d'exploitation requièrent une interface réseau, un logiciel de contrôle de bas niveau,
ainsi que des programmes qui permettent une connexion distante et un accès aux fichiers qui se trouvent
sur les différentes machines.
Exploitation en distribué
Les réseaux d'ordinateurs qui fonctionnent sous des systèmes d'exploitation distribués apparaissent
aux yeux des utilisateurs comme une machine monoprocesseur, même lorsque ce n'est pas le cas. Le
syst‫ث‬me d'exploitation distribué gère et contrôle l'ensemble des composants de tous les ordinateurs
connectés (les processeurs, les mémoires, les disques, etc.).
Systèmes multiprocesseurs
Ces systèmes sont composés de plusieurs processeurs reliés au bus de l'ordinateur. Ils se caractérisent
par leur capacité de traitement et leur fiabilité : la panne d'un processeur n'arrêtera pas le système.

7
Brevet de technicien supérieur (BTS2)-Ouarzazate-

CH II : GESTION DES PROCESSUS


1) concepts élémentaires :
 instruction : information élémentaire indécomposable. La nature de l’instruction est
fonction du langage considéré et son exécution peut être complexe.
 Programme : un ensemble des instructions ordonné.
 Chargement de programme : Pour être exécuté et donner naissance a un processus, un
programme et ses données sont chargées en mémoire centrale (flèche 1), puis les instructions sont
transférées individuellement de la mémoire centrale vers l’unité centrale de traitement (UCT), où elles
seront exécutées (fléche2).

UCT mémoire

Unité de
commande
Périphérique

UAL

registr
es 1 1
2 2

1.1) Processus et son espace adresse :


1.1.1) définition de processus :
Le processus, c’est l’exécution d’un programme comportant des instructions et des données (suite
temporelle d’exécution d’instructions) : c’est une entité dynamique crée à un instant donné. Le concept de
processus n’a donc de sens que dans le cadre d’un contexte d’exécution.
1.1.2) espace de travail :
Les processus sont composés d’un espace de travail en mémoire formé de 3 segments : pile,
données, code.

PILE

Données

code

8
Brevet de technicien supérieur (BTS2)-Ouarzazate-
 Le code correspond aux instructions, en langage d’assemblage, du programme à exécuter.
 La zone de données contient les variables globales ou statiques du programme ainsi que les
allocations dynamiques de mémoire.
 Les appels de fonctions, avec leurs paramètres et leurs variables locales viennent s’empiler sur la
pile.
1.2) Implémentation de processus :
Pour gérer les processus, le système d'exploitation sauvegarde plusieurs informations dans des
structures de données. Il existe une table (ou une liste chaînée) pour contenir les informations concernant
tous les processus crées. Il y a une entrée par processus dans la table, appelée le Bloc de Contrôle de
Processus (PCB).
Chaque entrée de la table PCB comporte des informations sur :
- Le pid du processus (c’est un numéro qui identifie le processus).
- L'état du processus.
- Son compteur ordinal (adresse de la prochaine instruction devant être exécutée par ce processus).
- Son allocation mémoire.
- Les fichiers ouverts qui sont utilisés par le processus.
- Les valeurs contenues dans les registres du processeur.
- Tout ce qui doit être sauvegardé lorsque l'exécution d'un processus est suspendue.
1.2.1) Changement de contexte de processus :
Une des principales raisons pour justifier l'existence des blocs de contrôle des processus est
que dans un système multiprogrammé on a souvent besoin d’allouer le CPU à un autre
processus. Il faut donc mémoriser toutes les informations nécessaires pour pouvoir
éventuellement relancer le processus courant dans le même état. Par exemple, il faut
absolument se rappeler à quelle instruction il est rendu. La figure ci-dessous illustre le

9
Brevet de technicien supérieur (BTS2)-Ouarzazate-
changement de contexte entre processus. Le processus en cours est interrompu et un
Ordonnanceur est éventuellement appelé.
1.3) Opérations sur les processus :
C’est l’ensemble des opérations qui permettent de créer et de manipuler les processus. l’ensemble de
ces opérations comprend :
- Création.
- Destruction
- Mise en attente/réveille.
- Suspension
1.3.1) création :
Un processus peut en créer un autre. Le premier est appelé père et le second fils. Le processus fils
peut créer à son tour d’autres processus. Dans le système UNIX de nouveaux processus sont crées par
l’appelle système fork().
1.3.2) destruction :
Un processus fils nouvellement crée peut se terminer de différentes façons :
- Il se termine normalement après l’exécution de la dernière instruction du programme associé.
- Il peut exécuter une instruction d’autodestruction, exemple : exit().
- Un processus peut être détruit par un autre processus.
Généralement la destruction d’un processus entraîne :
- La libération des ressources qui lui avait affecté.
- Le PCB est effacé. Il disparaît de la table des processus et des files d’attente du système
1.3.3) mettre en attente et réveiller :
Utilisé lorsqu’un processus a besoin de ressources autre que UCT (processeur), pour poursuivre son
exécution (fichier, imprimante …), il est alors placé par le système dans l’état en attente. Lorsque plus
tard le système est en mesure de lui affecte la ressource demandée, il réveille le processus en attente et le
met dans l’état prêt.
1.3.4) suspension :
Il s’agit d’un retrait temporaire d’un processus. L’opération amène un processus d’un état quelconque
à l’état suspendu.

10
Brevet de technicien supérieur (BTS2)-Ouarzazate-
1.4) Les cycles d’un processus :
L’exécution d’un processus est composé principalement de deux séquences : Séquence d’exécution
sur UCT et séquence d’attentes E/S où l’UCT est dans son temps mort (l’UCT est en repos).de cela on
peut distinguer de sort de programme :

Attente d’E/S Cycle d’E/S

Cycle d’UCT

Attente d’E/S Cycle d’E/S

Cycle d’UCT

Attente d’E/S

 Programmes demandants plus d’E/S s’appelle des programmes interactifs.


 Programmes demandants moins d’E/S s’appelle programme d’arrière plan.
Exemple :

Main()
{
int a, b, i ;

printf(” donner deux entiers ”) ;// affichage sur l’écran


scanf(”%d”,&a); //lecture à partir du clavier Cycle
scanf(”%d”,&a); d’E/S

for(i=1 ; i<10 ; i++) // traitement


{
a=a+1; Cycle d’UCT

b=b+1;
}

printf(“ la valeur a devient : %d”,a);


Cycle
printf(“ la valeur b devient: %d”,b);
d’E/S

11
Brevet de technicien supérieur (BTS2)-Ouarzazate-
Cet exemple peut montrer que les cycles d’E/S peut perdre le temps de l’UCT, en effet, pour ce
programme l’UCT doit attendre jusqu’à ce que l’utilisateur fasse entrer la valeur de a et b avant de
continuer le traitement.
1.5) les états fondamentaux d’un processus :
Le principe de la multiprogrammation consiste à loger simultanément plusieurs processus en
mémoire. Généralement l’idée de base est de commuter entre les processus ( exécuter le processus, puis le
suspendre pour exécuter un autre ) ce qui engendre 3 états fondamentaux de processus :
 Elu (running) : le processus est en train d’être traité par le processus.
 Bloqué (waiting) : le processus est en train d’attendre un évènement (ex : opération
d’E/S).
 Prêt : le processus est en attente d’être traité par le processus.

élu
➁ Réquisition (par
➀ blocage (attente
l’Ordonnanceur)
de données)

➂ relance

blo (par l’Ordonnanceur) prêt


qué

➃ déblocage

➀ - lorsqu’un processus doit attendre :

 Un service que le système d’exploitation ne peut offrir immédiatement.


 Un accès à une ressource pas encore disponible.
 Doit attendre la réponse d’un autre processus.

➁ - le système décide d’interrompre le processus pour activer un autre

➂ - lorsque l’Ordonnanceur choisit le processus pour le traitement

➃ - les données ( ou ressources ) deviennent disponibles au processus

1.5.1) La multiprogrammation sans préemption ( sans réquisition) :

12
Brevet de technicien supérieur (BTS2)-Ouarzazate-

élu

➀ blocage (attente

de données)

➂ relance
blo prê
(par l’Ordonnanceur)

➃ déblocage

Il n’y a pas la transition ➁ (élu -> prêt ) c’est à dire que le système choisit, parmi les processus en

état prêt, un processus en état élu que lorsque le processus en cours d’exécution est bloqué sue une E/S. ce
mode de fonctionnement ne convient pas à des environnements interactifs (nécessité beaucoup d’E/S).
1.5.2) La multiprogrammation avec préemption (avec réquisition) :

élu
➁ Réquisition (par
➀ blocage (attente
l’Ordonnanceur)
de données)

➂ relance
bl pr
(par l’Ordonnanceur)

➃ déblocage

il introduit la transition ➁ , permettant de faire passer un processus de l’état élu à l ‘état prêt sans que

celui-ci soit bloqué par une demande d’E/S . d ‘une autre manière le processus élu s’exécute sur le
processeur jusqu’à ce il soit bloqué sur une E/S ou que l’Ordonnanceur le fasse basculer en état prêt
2) ordonnancement de processus :
Programmes qui gèrent l’utilisation de ressources de l`ordinateur, trois types d`Ordonnanceurs
d ’UCT:
- À court terme (CPU Scheduler) : sélectionne quel processus doit exécuter la transition prêt →
élu.
- À long terme (job scheduler): sélectionne les processus nouvellement crée qui peuvent passer à
l’état prêt.
13
Brevet de technicien supérieur (BTS2)-Ouarzazate-
- À moyen terme: le manque de ressources peut parfois forcer le système d’exploitation à
suspendre des processus :
- Ils seront plus en concurrence avec les autres, pour les ressources.
- Ils seront repris (mis à l’état élu) plus tard quand les ressources deviendront disponibles.
Ces processus sont enlevés de mémoire centrale et mis en mémoire secondaire, pour être repris plus
tard.
2.1) répartiteur :

Programme qui donne le contrôle au processus choisi par l’ordonnanceur. Il doit se préoccuper de:
- changer de contexte
- changer à mode usager
- réamorcer le processus choisi
2.2) Évaluation des algorithmes d’ordonnancement :
Parmi les critères qui différencient un Ordonnanceur d’un système d’exploitation à un autre :
 Utilisation de l’ UCT : Pourcentage d’utilisation ( à maximiser) .
 Débit : nombre de processus qui complètent dans l’unité de temps (à maximiser).
 Temps de réponse (dans les systèmes interactifs) : le temps entre une demande et la réponse (à
minimiser).
 Temps d’attente : attente dans la file prêt – temps d’arrivée (à minimiser).
2.3) Les algorithmes d’ordonnancement :
2.3.1) premier arrivé, premier servi (PAPS=FIFO) :
Exemple :
Processus Temps de cycle
P1 24
P2 3
P3 3

14
Brevet de technicien supérieur (BTS2)-Ouarzazate-

P1 P2 P3
0
24 27 30

Si les processus arrivent au temps 0 dans l’ordre: P1, P2, P3


Le diagramme Gantt est:
Temps d’attente pour P1= 0 ; P2 = 24 ; P3 = 27 .
Temps d’attente moyen : (0 + 24 + 27) / 3 = 17
2.3.2) plus court servi (PCS) :
Le processus le plus court part le premier. Si un processus, qui dure moins que le reste du processus
courant, se présente plus tard, on distingue deux cas :
Avec préemption : le processus courant est interrompu.
Sans préemption : le processus courant continue son traitement.
Dans cet algorithme l’Ordonnanceur doit :
- Estimer la durée de chaque processus en attente.
- Elire le processus le plus court.
Exemple de PCS sans préemption :
Processus Temps d'arriver Temps de cycle
P1 0 7
P2 2 4
P3 4 1
P4 5 4

P1 P3 P2 P4
0 3 7 8
12 16
P2 arr. P3 arr. P4 arr

Temps d’attente moyen = (0 + 6 + 3 + 7)/4 = 4


15
Brevet de technicien supérieur (BTS2)-Ouarzazate-
PCS avec préemption :

P1 P2 P3 P2 P4 P1

0 2 4 5 7 11 16
P2 arr. P3 arr.

Temps moyen d`attente = (9 + 1 + 0 +2)/4 = 3


P1 attend de 2 à 11, P2 de 4 à 5, P4 de 5 à 7
Inconvénients du PCS :
- Difficulté d’estimer la longueur de processus à l’avance.
- Les processus longs souffriront de la famine (ne seront pas exécutés) lorsqu’il y a un apport
constant de processus courts.
La préemption est nécessaire pour les environnements à temps partagé : dans le cas de PCS sans
préemption un processus long peut monopoliser l’UCT s’il est le premier à entrer dans le système et il ne
fait pas d’E/S.

2.3.3) tourniquet :
Le processeur est alloué successivement aux différents processus, par tranches de temps de durée
fixe. Lorsqu'un processus se termine avant la fin de sa tranche de temps ou lorsque le processeur se trouve
en attente d'E/S, le processeur est alloué au processus suivant. Ceci permet d'exploiter au mieux le
processeur car il n'attend pas inutilement une ressource indisponible.

P1 P2 P3 CPU

Retourne à la fin de la file après un quantum

16
Brevet de technicien supérieur (BTS2)-Ouarzazate-
Exemple 1 :

Temps
Processus 1 Processus 2 Processus 3
Exécution

Lecture de fichier Exécution

Données disponibles Quantum écoulé Exécution


Exécution Affichage dans l'écran
Quantum écoulé Exécution
Ecriture dans le fichier Exécution
Exécution Données transférées Fin de processus
Lecture de fichier Exécution

Exemple 2 :

On suppose 4 processus arrivent


pratiquement en Processus Temps de cycle même temps, leurs
temps de cycle sont : P1 7
P2 4
P3 1
Prenons : P4 4 quantum = 3 ut

P1 P2 P3 P4 P1 P2 P4 P1

0 3 6 7 10 13 14 15 16

Temps d'attente de P1 : (10 - 3) + (15 -10) = 12.


Temps d'attente de P2 : (3-0) + (13 -6) = 10.
2.3.4) Ordonnancement a liste multiples :
Cette méthode appelé aussi « Recyclage à plusieurs files d’attente ». Avant d'accéder au processeur,
les processus sont rangés dans n files ( F0, F2,…,Fn-1 ) correspondant à leur niveau de priorité, à chaque
file Fi est associé un quantum de temps . Un processus ne peut accéder au processeur que s'il n'existe plus
de processus dans les files de plus haute priorité.
17
Brevet de technicien supérieur (BTS2)-Ouarzazate-

Les priorités peuvent être :


 externes, fixées avant la prise en compte du processus,
 internes, ajustées par le système,
 mixtes.

3) création des processus sous UNIX :


3.1) Notions sur le système Unix :
Le système UNIX est un système d’exploitation multitâches et multi- utilisateurs en temps partagé,
implantable sur tout ordinateur, assurant une portabilité des applications.
UNIX = le noyau + l'interpréteur de commandes ( Shell )+ des utilitaires
UNIX est construit autour de deux notions essentielles :
 Fichiers : organisés en structure arborescente
 processus : un processus correspond à l’exécution d’un programme (système ou utilisateur) et à
son environnement (descripteurs de fichiers, registres, compteur ordinal, …). La gestion de la mémoire
centrale constitue un aspect important du contrôle des processus.
3.2) Création de processus par appel a fork() :
Dés sa création un processus est doté d'un environnement de travail spécifique. Il est le fils du
processus qui l'a créé. Le premier processus, créé au démarrage du système, est donc le père de tous les
autres. La création d'un nouveau processus est l'un des mécanismes fondamentaux d'Unix. Le processus
père exécute une instruction appelée fork (fourche) qui crée le processus fils. Le père et le fils exécutent
alors les mêmes instructions du même code. L'exécution des deux processus continue après l'appel de
fork.

18
Brevet de technicien supérieur (BTS2)-Ouarzazate-

Modes de fonctionnement du père et du fils

La primitive exit termine la vie d'un processus fig.(a): c'est donc la dernière instruction du code. La
primitive wait indiquée place le père en attente jusqu'à la mort de son fils. Il ne reprendra son activité
qu'après sa disparition.
3.3) Identification de processus :
En testant la valeur de l'identificateur on peut distinguer le père du fils donc décider de leur faire
exécuter des codes différents et changer l'environnement du fils. On distingue le père du fils par la valeur
renvoyée par fork :
• 0 dans le processus fils ;
• Le numéro d'identification (PID) du processus fils créé dans le processus père.

Identification du processus

De plus la primitive exec permet de charger un nouveau code. Ainsi le fils peut-il exécuter un
programme différent de celui de son père
Pour savoir le créateur du processus père (le père du père) on peut utiliser la commande ps. Les
fonctions getpid() et getppid() permettent l'affichage de PID de processus fils et du PID de son père.
3.4) Etats des processus sous Unix :
19
Brevet de technicien supérieur (BTS2)-Ouarzazate-
Un processus peut prendre l'un des 9 états décrits dans /usr/include/sys/proc.h , parmi lesquels :
 actif : en mode utilisateur (pas de droit d'accès aux ressources du système) ou en
mode système (ou noyau)
 activable ou prêt à exécuter : en mémoire ou en zone de swap. Il est éligible par
l'ordonnanceur. Ces deux états sont codés R
 bloqué : en attente d'un événement (horloge, montage d'un disque, résultat d'un
autre processus, ...), en mémoire ou en zone de swap. Il ne consomme pas de temps CPU. Il repasse à
l'état activable dès que les conditions le permettent. Cet état est Désigné par S (sleep)
 non prêt : en création ou zombie (désigné par Z, le processus est achevé, mais son
père n'en a pas encore connaissance). Il ne consomme pas de temps CPU.

NOUVEAU
FIN
1

3
2 ACTIF ACTIF
PRET
4
UTILISATEUR
7
8 5 9
6

7
SUSPENDU

1 : le processus créé par fork a acquis les ressources nécessaires à son exécution
2 : le processus vient d'être élu par l'ordonnanceur
3 : le processus revient d'un appel système ou d'une interruption
4 : le processus a réalisé un appel système ou une interruption est survenue
5 : le processus se met en attente d'un événement (libération de ressource, terminaison de processus
par wait). Il ne consomme pas de temps UC
6 : l'événement attendu par le processus s'est produit
7 : conséquence d'un signal particulier
8 : réveil du processus par le signal de continuation SIGCONT
9 : le processus s'achève par exit, mais son père n'a pas pris connaissance de sa terminaison. Il ne
consomme pas de temps UC et ne mobilise que la ressource table des processus
La commande ps propose 4 options :
* - a (tous les processus attachés au terminal),
* - e (tous les processus),
20
Brevet de technicien supérieur (BTS2)-Ouarzazate-
* - f (full : plus de renseignements),
* - l (long : presque tous les renseignements).
Les champs de la tables des processus qui sont édités sont les suivants en fonction des options - f ou -
l:
F (- l) localisation d'un processus (0 = hors MC, 1 = en MC, 2 processus système, 4 =
verrouillé car en attente de fin d'E/S, 10 = en vidage)
S ( -l) state (O = non existant, S = sleeping, W = waiting, R = running, Z = zombie, X = en
évolution, P = pause, I = attente d'entrée au terminal ou input, L = attente d'un fichier verrouillé ou
locked)
4) synchronisation de processus :
Les processus s’exécutant dans le système d’exploitation peuvent être des
processus coopératifs ou indépendants.
les processus indépendants sont des processus qui ne partagent pas les ressources systèmes entre
eux.
les processus qui partagent les ressources systèmes sont des processus coopératif on dit aussi des
processus concurrents
En présence de coopération il y a la Nécessité de synchroniser les processus : Influer sur l’ordre dans
lequel elles s’exécutent.
Les ressources systèmes peuvent être :
Ressources physiques (à partager car en nombre insuffisant) :
• Processeur, disque, imprimante, …
Ressources logiques (leur rôle est de conserver ou mémoriser des données, un état commun)
• Données globales du système d’exploitation
• Zones de mémoire partagée
• Fichiers d’une base de données
Une mauvaise synchronisation des processus peut produire des incohérences de données comme le
montre l’exemple ci-dessous :
Exemple 1 :
Soit deux Processus P1 et P2 exécutent cette même procédure et partagent la même variable “a” :
static char a;
void echo()
{
scanf("%c", &a);
printf ("%c",a);
}
21
Brevet de technicien supérieur (BTS2)-Ouarzazate-

P1 et P2 peuvent être interrompus n’importe où, Si P1 est interrompu après “scanf” et que P2
s’exécute au complet.

P1 P2

static char a; static char a;


void echo() void echo()
{ {
scanf("%c", &a);
scanf("%c", &a);
printf ("%c",a);

printf ("%c",a);
} }

Le caractère affiché par P1 sera alors celui lu par P2 !!!


Le résultat de l’exécution concurrente de P1 et P2 dépend de l`ordre de leur entrelacement.
Exemple 2:
Considérons la procédure suivante de mise à jour d’un compte bancaire d’un client. Pour simplifier,
on considère qu’un compte est implémenté par un simple fichier qui contient le solde courant du client:

crediter_compte ( entier numero_client, entier somme)


entier solde ;
debut
solde = lire_dans_fichier (numero_client); /* lecture du solde dans le fichier du client */
solde = solde + somme ;
ecrire_dans_fichier(numero_client, solde) ; /* écrire dans le fichier le nouveau solde */
fin;

Supposons maintenant que cette même procédure est exécutée simultanément par deux processus P0
et P1 dans un système d’exploitation à temps partagé. Sans faire aucune hypothèse sur la durée du
quantum, on peut faire les exécution suivantes :

22
Brevet
P0 : crediter_compte( de technicien
1233, 1000) supérieur (BTS2)-Ouarzazate-
P1 : crediter_compte( 1233, 500)

solde = lire_dans_fichier(1233) ; solde = lire_dans_fichier(1233) ;

/* P0 bloqué car P1 s’exécute */ solde=solde+1000 ;

solde=solde+500 ; /* P1 bloqué car P0 s’exécute */

Ecrire_dans_fichier(1233,solde) ; Ecrire_dans_fichier(1233,solde) ;

Comme le montre cet exemple, le résultat final n’est pas le résultat escompté (le client a perdu 500F
dans cet affaire ).
4.1) section critique :
Le problème dans le programme précédent est dû aux conflits d’accès au même fichier. Ces accès
sont en lecture et en écriture.
On appelle section critique la partie d’un programme où se produit le conflit d’accès.

crediter_compte ( entier numero_client, entier


somme)
entier solde ;
debut
solde = lire_dans_fichier (numero_client);
solde = solde + somme ; SC
ecrire_dans_fichier(numero_client, solde)
fin;

SC: Section critique: partie d’un programme dont


l’exécution ne doit pas entrelacer avec autres
programmes

Comment éviter ces conflits d’accès ?


Il faut trouver un moyen d’interdire la lecture ou l’écriture des données partagées à plus d’un
processus à la fois.

23
Brevet de technicien supérieur (BTS2)-Ouarzazate-
Il faut une exclusion mutuelle, c’est à dire empêcher les autres processus d’accéder à des données
partagées si celles-ci sont en train d’être utilisées par un processus
Dans l’exemple précédent, il faut obliger le processus P1 à attendre la terminaison de P0 avant
d’exécuter à son tour la même procédure (exclusion mutuelle)
Pour une bonne coopération entre processus :
Pour que les processus qui partagent des objets (données en mémoire centrale,
Fichiers…) puissent coopérer correctement et efficacement, quatre conditions sont nécessaires :
1. Exclusion mutuelle : deux processus ne peuvent être en même temps en section critique

2. Famine : aucun processus ne doit attendre trop longtemps avant d’entrer en section critique

3. Interblocage (deadlock) : aucun processus suspendu en dehors d’une section critique ne doit
bloquer les autres d’y entrer . La dernière section sera consacrée à l’étude de ce problème
4. Aucun hypothèse ne doit être faite sur les vitesses relatives des processus
4.2) Exclusion mutuelle avec attente active :
Les solutions de l’attente active consistent à gérer les problèmes d’accès concurrent sans intervention
ou aide de la part de système d’exploitation. Elles ne sont pas applicable aux cas généraux, puisqu’elle
suppose que les processus accédant aux ressources s’exécutent à la même vitesse, et font des accès en
alternance.
Exemple :
Cet algorithme repose sur un compteur tour qui indique l’identifiant de processus qui a le droit
d’utiliser la ressource qui est partagé entre deux processus.
Lorsqu’un processus a terminé sa section critique, il incrémente tour, modulo le nombre de
processus, pour que sa valeur pointe sur le processus suivant.
Lorsqu’un processus est en attente de l’allocation de la ressource, il exécute une boucle infinie.
C’est le fait d’exécuter de commandes inutiles (la boucle infinie) qui forme la caractéristique
principale de l’attente active : un processus en attente occupe le processeur avec des opérations inutiles.

Processus A Processus B
While(TRUE) While(TRUE)
{ {
While(tour !=0) {} ; While(tour !=1) {} ;
/*attente*/ /*attente*/
Section_critique () ; Section_critique () ;
Tour=1 ; Tour=0 ;
Section_non_critique() ; Section_non_critique() ;
} }
24
Brevet de technicien supérieur (BTS2)-Ouarzazate-

Cette solution ne satisfait pas la quatrième condition. Supposons par exemple :


Le processus A est un processus très rapide, et qu’il vient de terminer sa section critique.
Le processus B est très lent, est actuellement en section non critique, et n’aura pas besoin d’entrer en
section critique avant très longtemps.
Le processus A termine rapidement sa section non critique, et veut à nouveau entrer en section
critique. Il ne pourra pas, puisque la variable tour n’est pas positionnée correctement.
4.3) sémaphores :
La synchronisation par sémaphore ou flag est un moyen simple et ancien de synchroniser des
processus parallèles. Le principe est directement hérité des chemins de fer d'où son nom : lorsque le
sémaphore est levé, le processus P peut continuer son chemin; lorsqu'il est baissé il doit attendre jusqu'à
ce qu'un autre processus Q le lève. P et Q sont l'équivalent de deux trains roulant sur deux voies distinctes
qui doivent se synchroniser pour pouvoir franchir un croisement sans accident.
 Dans le modèle le plus simple il existe trois primitives:
lever (c) fait passer le sémaphore c de la valeur "baissé" à "levé".
baisser(c) fait passer le sémaphore c de "levé" à "baissé".
flag(c) retourne vrai si le sémaphore c est baissé.
Les sémaphores sont des variables communes mises à la disposition des différents processus par le
système d'exploitation qui peuvent les consulter, les modifier et sur lesquelles ils peuvent se mettre en
attente.
Prenons l'exemple du transfert de résultats au moyen d'un tampon, Le fonctionnement est le suivant:
Processus P : Processus Q :
baisser(e); lever(f);
while (calculs à faire){ while (éléments à transférer) {
calculs des éléments du tampon (a); if (flag(e)) {
baisser(e); attendre(e)
}
if (flag(f)) {
attendre(f); baisser(f);
} lire tampon(a);
écrire tampon (a); lever(f);
lever(e); }
}

Les sémaphores sont un moyen de résoudre le problème que les variables e et f pouvaient être
communes à l'ensemble des processus. Ces variables ne peuvent prendre que deux valeurs. Elles doivent
être déclarées au moyen d'instructions spéciales qui précisent les noms des processus qui peuvent les
25
Brevet de technicien supérieur (BTS2)-Ouarzazate-
partager. Les sémaphores sont un moyen simple de synchronisation mais il est difficiles, comme nous
l'avons vu, de se prémunir complètement contre les risques d'interblocage.
On peut sophistiquer le modèle du sémaphore en y associant des compteurs à valeurs entières
associés à des files d'attente. Ceci permet de gérer plusieurs processus qui doivent se partager une
ressource unique. Imaginons N processus Pi qui calculent et remplissent des tampons distincts, de la
même façon que le processus P que nous venons d'étudier. Un seul processus Q est chargé du transfert
des résultats sur le disque pour tous les processus P. Il ne peut traiter qu'un seul tampon à la fois. Il faut
deux sémaphores pour synchroniser les processus Pi et Q. Il faudrait donc prévoir 2N sémaphores lors de
la programmation du transfert. Ceci est rigide et ne permet pas facilement de changer le nombre de
processus. Si on ajoute une file d'attente associée au sémaphore f il devient possible de gérer un nombre
indéterminé de processus avec ce sémaphore unique. Imaginons par exemple un sémaphore s. On lui
associe un compteur s.c et une file d'attente s.f.
Un processus emploiera le sémaphore au moyen de deux procédures:
 stop(s) qui arrête éventuellement le processus.
 start(s) qui active éventuellement le processus.
Lorsque la valeur du sémaphore est négative tous les processus inscrits dans sa file d'attente sont
bloqués.
Schématiquement le fonctionnement de ces procédures est le suivant :
stop(s) start(s)
{ {
s.c = s.c - 1; s.c = s.c + 1;
if (s.c < 0) { if (s.c <= 0) {
attendre(); Sortir(s.f);
entrer (s.f); activer();
} }

} }

attendre() et activer() mettent le processus en attente ou le réactive, entrer(s.f) et sortir(s.f) sont deux
fonctions qui incluent et extraient le processus de la file d'attente f associée au sémaphore s. On
remarquera que si stop(s) peut bloquer le processus qui l'utilise. start(s) n'est jamais bloquante.

4.4) problèmes classiques de synchronisation de processus :


4.4.1) problèmes de producteurs et consommateurs :
Les processus ont besoin de communiquer, d'échanger des informations de façon plus élaborée et
plus structurée que par le biais d'interruptions. Un modèle de communication entre processus avec partage
de zone commune (tampon) est le modèle producteur-consommateur.

26
Brevet de technicien supérieur (BTS2)-Ouarzazate-
Le producteur doit pouvoir ranger en zone commune des données qu'il produit en attendant que le
consommateur soit prêt à les consommer. Le consommateur ne doit pas essayer de consommer des
données inexistantes.
Hypothèses :
- les données sont de taille constante
- les vitesses respectives des deux processus (producteur consom-mateur) sont quelconques.
Règle 1 : Le producteur ne peut pas ranger un objet si le tampon est plein
Règle 2 : Le consommateur ne peut pas prendre un objet si le tampon est vide.
PRODUCTEUR CONSOMMATEUR
Faire toujours: Faire toujours :
produire un objet si: nb d'objets ds tampon >0
si: nb d'objets ds tampon < N alors : prendre l'objet
alors : déposer l'objet ds le tampon
finsi finsi
Fait Fait

Règle 3 : exclusion mutuelle au niveau de l'objet : le consommateur ne peut prélever un objet que le
producteur est en train de ranger.
Règle 4 : si le producteur (resp. consommateur) est en attente parce que le tampon est plein (resp.
vide), il doit être averti dès que cette condition cesse d'être vraie.
Le tampon peut être représenté par une liste circulaire. On introduit donc deux variables caractérisant
l'état du tampon :
NPLEIN : nombre d'objets dans le tampon (début : 0)
NVIDE : nombre d'emplacements disponibles dans le tampon (N au début).
PRODUCTEUR :
Faire toujours
Produire un objet /* début d'atome ininterruptible */
si NVIDE >0 /* s'il existe au moins un emplacement vide dans le
tampon */
alors NVIDE --
sinon s'endormir
finsi /* fin d'atome ininterruptible */
ranger l'objet dans le tampon /* début d'atome ininterruptible */
si consommateur endormi
alors réveiller le consommateur

27
Brevet de technicien supérieur (BTS2)-Ouarzazate-
sinon NPLEIN ++
finsi
Fait

CONSOMMATEUR :
Faire toujours
si NPLEIN > 0 /* s'il existe au moins un objet dans le tampon */
alors NPLEIN --
sinon s'endormir
finsi
prélever l'objet dans le tampon
si producteur endormi
alors réveiller le producteur
sinon NVIDE ++
finsi
consommer l'objet
Fait
4.4.2) problème des philosophes dîneurs :
Il s'agit d'un problème très ancien, dont DIJKSTRA a montré en 1965 qu'il modélise bien les
processus en concurrence pour accéder à un nombre limité de ressources. "5 philosophes sont assis autour
d'une table ronde. Chaque philosophe a devant lui une assiette de spaghettis si glissants qu'il lui faut
deux fourchettes pour les manger. Or, il n'y a qu'une fourchette entre deux assiettes consécutives.
L'activité d'un philosophe est partagée entre manger et penser. Quand un philosophe a faim, il tente de
prendre les deux fourchettes encadrant son assiette. S'il y parvient, il mange, puis il se remet à penser.
Comment écrire un algorithme qui permette à chaque philosophe de ne jamais être bloqué ? "

Il faut tout à la fois éviter les situations :

28
Brevet de technicien supérieur (BTS2)-Ouarzazate-
- d'interblocage : par exemple tous les philosophes prennent leur fourchette gauche en même
temps et attendent que la fourchette droite se libère
Voici une solution :
#define N 5 /* nombre de philosophes */
#define GAUCHE (i - 1) % N /* n° du voisin gauche de i */
#define DROITE (i + 1) % N /* n° du voisin droite de i */
#define PENSE 0 /* il pense */
#define FAIM 1 /* il a faim */
#define MANGE 2 /* il mange */
typedef int semaphore;
int etat [N]; /* pour mémoriser les états des philosophes */
semaphore mutex = 1, /* pour section critique */
s [N]; /* un sémaphore par philosophe */
/*****************************/
void philosophe (int i)
{
while (TRUE)
{
penser ();
prendre_fourchettes (i); /* prendre 2 fourchettes ou se
bloquer */
manger ();
poser_fourchettes (i);
}
}
/*****************************/
void prendre_fourchettes (int i)
{
P (mutex); /* entrée en section critique */
etat [i] = FAIM;
test (i); /* tentative d'obtenir 2 fourchettes */
V (mutex); /* sortie de la section critique */
P (s [i]); /* blocage si pas 2 fourchettes */
}

29
Brevet de technicien supérieur (BTS2)-Ouarzazate-
/*****************************/
void poser_fourchettes (int i)
{
P (mutex); /* entrée en section critique */
etat [i] = PENSE;
test (GAUCHE);
test (DROITE);
V (mutex) ; /* sortie de la section critique */
}
/*****************************/
void test (int i)
{
if (etat [i] == FAIM && etat [GAUCHE] != MANGE && etat [DROITE] !=
MANGE)
{
etat [i] = MANGE;
V (s [i] );
}
}
5) études de cas : UNIX.
5.1) principe des sémaphores sous unix :
Pour créer un sémaphore, l'utilisateur doit lui associer une clé. le système lui renvoie un identificateur
de sémaphore auquel sont attachés n sémaphores numérotés de 0 à n-1. Pour spécifier un sémaphore
parmi les n, l'utilisateur indique l'identificateur et le numéro du sémaphore.
A chaque identificateur de sémaphore sont associés des droits d'accès. Ces droits sont nécessaires
pour effectuer des opérations sur les sémaphores, mais inopérants pour :
- la destruction d'un identificateur de sémaphore,
- la modification des droits d'accès.
Seul le créateur, le propriétaire ou le super-utilisateur peuvent réaliser ces opérations.
1. Le fichier <sys/sem.h>
A chaque ensemble de sémaphores sont associées les structures semid_ds (une par ensemble de
sémaphores), __sem et sembuf (une par sémaphore) décrites dans <sys/sem.h>
struct __sem /* correspond à la structure d'un sémaphore dans le noyau */
{
unsigned short semval; /* valeur du sémaphore */

30
Brevet de technicien supérieur (BTS2)-Ouarzazate-
unsigned short sempid; /* pid du dernier processus utilisateur */
unsigned short semcnt;
/* nombre de processus attendant l'incrémentation du sémaphore */
unsigned short semzcnt;
/* nombre de processus attendant que semval soit nul */
};
struct sembuf /* correspond à une opération sur un sémaphore */
{
unsigned short sem_num; /* n° de sémaphore : 0,.... */
short sem_op; /* opération sur le sémaphore */
short sem_flg; /* option */
};
struct semid_ds
/* correspond à la structure d'une entrée dans la table des sémaphores */
{
struct ipc_perm sem_perm;/* les droits */
struct __sem * sem_base; /* pointeur sur le premier sémaphore de l'ensemble */
time_t sem_otime; /* date dernière opération par semop */
ushort sem_nsems; /* nombre de sémaphores de l'ensemble */
time_t sem_ctime; /* date dernière modification par semctl */
};
2. La fonction semget
int semget ( key_t cle, int nb_sem, int option)
nb_sem : nombre de sémaphores de l'ensemble
cle : si cle = IPC_PRIVATE, un nouvel ensemble de sémaphores est créé sans clé d'accès sinon, il y
a appel a ftok.
si cle ne correspond pas à un ensemble de sémaphores existant
si IPC_CREAT n'est pas positionné : erreur et retour de -1
sinon, un nouvel ensemble de sémaphores est créé et associé à cette clé. Les droits d'accès sont ceux
mentionnés; le propriétaire et créateur est le propriétaire effectif du processus; le groupe propriétaire et
créateur est le groupe propriétaire effectif du processus
 sinon si IPC_CREAT et IPC_EXCL sont tous deux positionnés :
erreur et retour de –1 sinon la fonction retourne l'identificateur de l'ensemble de sémaphores
option : on peut combiner par | des droits d'accès et les constantes suivantes :
SEM_A : permission de modification

31
Brevet de technicien supérieur (BTS2)-Ouarzazate-
SEM_R : permission en lecture
IPC_CREAT , IPC_EXCL
La fonction : key_t ftok (char * path , int id) utilise une chaîne de caractères (en principe un nom de
fichier unique dans le système ), la combine à id pour générer une clé unique dans le système, sous
forme d'un key_t (équivalent à un entier long).
Exemple : récupération de l'identificateur d'un ensemble de 5 sémaphores
num = semget (ftok (path, cle), 5, 0)
Exemple : /* création de 4 sémaphores associés à la clé 456 */
#include <errno.h>
#define CLE 456
main ()
{
int semid ; /* identificateur des sémaphores */
char *path = "nom_de_fichier_existant";
if (( semid = semget (ftok (path, (key_t) CLE) , 4, IPC_CREAT | IPC_EXCL | SEM_R |
SEM_A)) == -1)
{
perror ("échec de semget\n");
exit (1);
}
printf (" identificateur de l'ensemble : %d\n", semid);
printf ("clé de l'ensemble : %d\n", ftok (path, (key_t) CLE));
}
3. La fonction semctl
int semctl ( int semid, int semnum, int cmd, arg)
semid : identificateur de l'ensemble de sémaphores
semnum : numéro du sémaphore traité
union semun
{
int val;
struct semid_ds *buf;
ushort array [ <nb de sémaphores>];
} arg;
cmd : paramètre de commande pouvant prendre 10 valeurs :
GETVAL : retourne la valeur du sémaphore de n° semnum

32
Brevet de technicien supérieur (BTS2)-Ouarzazate-
SETVAL : le sémaphore de n° semnum reçoit la valeur arg.val
GETPID : retourne le pid du processus qui est intervenu en dernier lieu
GETNCNT : retourne le nombre de processus en attente d'une incrémentation de la valeur du
sémaphore de n° semnum
 GETZCNT : retourne le nombre de processus en attente du passage à 0 du sémaphore de n°
semnum
GETALL : range les valeurs de tous les sémaphores dans le tableau pointé par arg.array
SETALL : positionne les valeurs de tous les sémaphores à l'aide des valeurs du tableau pointé par
arg.array
IPC_STAT : la structure associée à semid est rangée à l'adresse contenue dans arg.buf
IPC_SET : positionne les valeurs gid, uid et mode à partir de la structure pointée par arg.buf
IPC_RMID : détruit le sémaphore
4. La fonction semop
int semop (int semid, struct sembuf (* sops) [ ], int nbops)
retourne semval du dernier sémaphore manipulé ou -1 en cas d'erreur
semid : identificateur de l'ensemble de sémaphores
sops : pointeur vers un tableau de nbops structures de type sembuf
Pour chaque sémaphore de n° sem_num (0 à nbops-1), on indique dans le champ sem_op
l'opération à effectuer avec un code entier :
si sem_op > 0 : semval = semval + sem_op
si sem_op = 0 : si semval = 0, rien n'est effectué
 sinon le processus est endormi en attendant la nullité de semval
si sem_op < 0: si semval >= |sem_op|, alors semval  semval - |sem_op|
sinon, le processus est endormi jusqu'à : semval >= |sem_op|
Pour le champ sem_flg :
s'il vaut IPC_NOWAIT, évite le blocage de processus et retourne un code d'erreur
s'il vaut SEM_UNDO, on évite de bloquer indéfiniment des processus sur des
sémaphores après la mort accidentelle d'un processus. Très coûteux en temps CPU et en mémoire
a) les opérateurs p et v :
(WAIT et SIGNAL au sens de DIJKSTRA)
/* Appelons ce fichier par exemple : "Dijkstra.h"
Il est évidemment à inclure dans le programme utilisateur*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

33
Brevet de technicien supérieur (BTS2)-Ouarzazate-
/*************************************************************/
int sem_create (key_t CLEF, int initval)
/* crée un ensemble d'un seul sémaphore dont la clé est reliée à CLEF, de valeur initiale initval
retourne l'identifiant associé au sémaphore si OK, sinon retourne -1 . Si l'ensemble associé à CLEF
existe déjà, la fonction part en échec.
 Les droits sont positionnés de sorte que tout processus peut modifier le sémaphore */
{ union semun {
int val;
struct semid_ds *buf;
ushort *array;
} arg_ctl;
int semid;
semid = semget ( ftok ("Dijkstra.h-<votre login>", CLEF), 1, IPC_CREAT | IPC_EXCL
| 0666);
if (semid == -1) return -1;
arg_ctl.semval = initval;
if (semctl (semid, 0, SETVAL, arg_ctl) == -1) return -1;
return semid;
}
/********************************************************/
int sem_delete ( int semid)
/* supprime l'ensemble de sémaphores identifiés par semid */
{
return semctl (semid , 0 , IPC_RMID , 0) ;
}
/********************************************************/
int P (int semid)
{
struct sembuf sempar;
sempar.sem_num = 0;
sempar.sem_op = -1;
sempar.sem_flg = SEM_UNDO;
return semop (semid , &sempar , 1);
}
/********************************************************/

34
Brevet de technicien supérieur (BTS2)-Ouarzazate-
int V (int semid)
{
struct sembuf sempar;
sempar.sem_num = 0;
sempar.sem_op = 1;
sempar.sem_flg = SEM_UNDO;
return semop (semid , &sempar , 1);
}
En outre, la commande shell ipcs permet d'obtenir des informations sur les objets de type
ensemble de sémaphores (et plus généralement tous les IPC), avec l'option : - s pour se limiter aux
sémaphores
- m pour se limiter aux segments de mémoire
- q pour se limiter aux files de messages
- c pour faire apparaître l'identité de l'utilisateur créateur
Elle fournit :
T: type de l'objet (q, m ou s)
ID : identification interne de l'objet
KEY : clé de l'objet en hexadécimal
MODE : droits d'accès à l'objet. Les 2 premiers des 11 caractères indiquent des
informations spécifiques à une file de messages ou à un segment de mémoire partagée
OWNER : identité du propriétaire
GROUP : identité du groupe propriétaire
5.2) Exemple de programmation concurrente :
main ()
{
int i, CLE = 33, mutex = 0;
if ((mutex = sem_create ( CLE, 1)) == -1)
{
perror ("problème de création du sémaphore ");
exit (-1);
}
printf ("création du sémaphore d'identifiant %d\n", mutex);
if (fork () == 0)
{
printf ("je suis le processus %d, fils de %d\n", getpid (), getppid ());

35
Brevet de technicien supérieur (BTS2)-Ouarzazate-
for (i = 0; i < 3 ; i++)
{
P (mutex);
printf ("le fils entre dans sa section critique\n");
sleep (15);
printf ("le fils sort de sa section critique\n");
V (mutex);
}
exit (0);
}
else {
for (i = 0 ; i < 4 ; i++)
{
P (mutex);
printf ("le pere entre dans sa section critique\n");
sleep (10);
printf ("le pere sort de sa section critique\n");
V (mutex);
}
wait (0);
printf ("FIN !\n");
sem_delete (mutex);
} }

36
Brevet de technicien supérieur (BTS2)-Ouarzazate-

37