Infotro/ptr (#23)

This commit is contained in:
Rémi Heredero authored and GitHub committed 2024-03-24 18:09:50 +01:00
commit bdaa3e1ce4
8 files changed
+255 -7

No files matched your search

+248 -5
View File
@@ -20,8 +20,8 @@ Cela permet d'éviter de bloquer toutes les applications lorsqu'une seule est en
La programmation concurrente sur plusieurs CPU permet en plus un gain de temps.
# Exclusion mutuelle
un programme est une entité statique
un processus est une entité dynamique
- un programme est une entité statique qui contient des processus
- un processus est une entité dynamique (il s'agit d'une tâche en cours d'exécution)
Les processus ne sont jamais totalement indépendants.
Ils partagent des ressources (mémoire, fichiers, périphériques, variable, etc.)
@@ -196,7 +196,7 @@ Sinon, **un** processus peut modifier la ressource et aucun peut lire.
```cpp
void BeginRead(void) {
osSemaphoreAcquire(rw, osWaitForever);
osSemaphoreAcquire(mutexNbReader, osWaitForever); // ENTER CRITICAL SECTION
osSemaphoreAcquire(mutexNbReader, osWaitForever); // ENTER CRITICAL SECTION
nbReader++;
if(nbReader == 1) osSemaphoreAcquire(w, osWaitForever);
osSemaphoreRelease(mutexNbReader); // EXIT CRITICAL SECTION
@@ -221,13 +221,98 @@ void EndWrite(void) {
}
```
# Coopération-Synchronisation
La coopération entre processus implique la synchronisation entre eux pour éviter de ressource.
## Évènement
L'évènement est un outil permettant de résoudre un problème de synchronisation comme les sémaphores ou les mutex.
On peut manipuler les évènements :
- ***Wait()*** : Attendre un évènement
- ***Signal()*** : Déclencher un évènement
- ***Init()*** : Initialiser un évènement
On peut aussi résoudre un problème de synchronisation entre processus avec un sémaphore initialisé à 0. On peut le comparer
à une barrière déclenchable depuis un autre processus.
# Synchronisation
Les sémaphores ne permettent pas de résoudre tous les problèmes de synchronisation. Trop grand risque de DEADLOCK.
Il faut utiliser d'autres outils plus performants.
## Le moniteur (monitor)
On peut l'imager avec une classe entièrement protégée par des sémaphores pour l'accès au variable et fonction (procédure).
Etat d'un processus :
Le moniteur possède comme primitive :
- ***x.wait*** : bloque le processus jusqu'à ce qu'un x.send soit émis.
- ***x.send*** : débloque le processus qui attend sur un x.wait.
```pascal
monitor M;
defines DepositeChar, TakeChar;
var
c : char;
chAvailable : boolean;
x : signal;
procedure TakeChar(var ch:char);
begin
if not chAvailable then x.wait end if;
ch := c;
chAvailable := FALSE
end TakeChar;
procedure DepositeChar(ch:char);
begin
c := ch;
chAvailable := TRUE;
x.send
end DepositeChar;
begin
chAvailable := FALSE
end M;
```
```pascal
process Keyboard;
uses M;
var cRead: char;
begin
...
Read a character on keyboard
Put it in the cRead variable
M.DepositeChar(cRead);
...
end Keyboard;
process Screen;
uses M;
var cWrite: char;
begin
...
M.TakeChar(cWrite);
Write the character cWrite on the screen
...
end Screen;
```
## Producteurs / consommateurs
Le problème survient lorsque le producteur envoie un message au consommateur via une queue.
[Example](https://git.kb28.ch/Klagarge/PTR-Queue/src/branch/master/main.c)
- ***Le producteur*** (Producer) doit être mis en attente s'il veut déposer un message alors que le tampon est plein
- ***Le consommateur*** (Consumer) doit être mis en attente s'il veut prélever un message alors que le tampon est vide
- ***Le producteur*** (Producer) en attente doit être débloqué dès que le consommateur (Consumer) prélève un message
- à ce moment le tampon n'est plus plein
- ***Le consommateur*** (Consumer) en attente doit être débloqué dès que le producteur (Producer) dépose un message
- à ce moment le tampon n'est plus vide
On peut résoudre aisément le problème producteurs-consommateurs avec un moniteur ainsi qu'avec un sémaphore.
<b><u>Solution à chier :</u></b><br>
Le producteur attend que le consommateur soit capable de réceptionner le message, ainsi les deux peuvent
continuer leurs exécutions (principe de rendez-vous). Ce concept ne possède pas de buffer.
# Allocation processeur
État d'un processus :
![img_1.png](img_1.png)
@@ -238,3 +323,161 @@ contiennent le registre de status et un pointeur sur sa stack. Ils sont utilisé
3. Il va prendre le descripteur du prochain processus et utiliser ses registres.
4. Le processus continue jusqu'au nouveau switching context.
## Cycle processeur
Un processeur réalise alternativement une suite de :
- ***Cycles processeur*** (CPU burst cycle)
- ***Cycles d'entrée-sortie*** (I/O burst cycle)
Lorsque le temps de cycle processeur est petit et qu'il y a une attente engendrée par les entrées-sorties, il est pertinent de partager
le processeur entre plusieurs processus.
## Queues d'ordonnancement
Les processus en attente du processeur sont placés dans une liste appelée **queue de processus prêts** (ready queue).
Cette queue peut être gérée comme une file FIFO, une liste de priorité, un arbre, une pile, une liste non-ordonnée, etc.
Cette queue est sous forme d'une liste chaînée qui contient des pointeurs sur les descripteurs de processus.
Les processus qui ont besoins d'une ressource sont placés dans une liste d'attente correspondant à la ressource (mutex/sémaphore).
L'ensemble des queues peut être regroupé dans le diagramme de synthèse suivant :
![synthese_diagram_queue_process.png](medias/synthese_diagram_queue_process.png)
## Ordonnanceurs
![ordonnanceur.png](medias/ordonnanceur.png)
### Ordonnanceur à court terme
- Sélectionne un nouveau processus toutes les millisecondes.
- Doit être très rapide
- Est très simple
### Ordonnanceur à long terme
- Contrôle le degré de multiprogrammation, c'est-à-dire, le nombre de processus en mémoire.
- Assure que la charge globale du processeur soit répartie équitablement entre les processus réalisant beaucoup d'entrée-sorties et les
processus réalisant beaucoup de calculs.
- S'exécute peu fréquement
- La complexité de ce dernier augmente fortement.
### Le swapping
On peut augmenter la RAM avec de la mémoire virtuelle (swap) pour garder les processus et ne pas les mettre en stockage
long termes.
### Distributeur de tâches
Il distribue au processeur les processus sélectionnés par l'ordonnanceur court terme.
- Il charge les registres du processus sélectionné
- Il change en mode utilisateur depuis le superviseur. Ce dernier servant à modifier les registres.
- Il met à jour le PC
## Critères de performance
- ***Efficacité** (CPU utilisation) : Taux d'utilisation du processus
- ***Débit*** (troughtput) : Nombre de processus par unité de temps
- ***Temps global*** (turnaround time) : Temps qui s'écoule entre la soumission du processus et la fin de son exécution
- ***Temps d'attente*** (waiting time) : Temps d'attente d'un processus dans la queue des processus prêts
- ***Temps de réponse*** (response time) : intervalle de temps entre l'heure de soumission et l'heure de la première réponse
## Algorithme d'ordonnancement
L'allocateur du processeur doit sélectionner quels processus situés dans la queue des processeurs prêts doivent recevoir le processeur.
### FIFO
L'algorithme FIFO est le plus simple. Il sélectionne le premier processus de la queue des processus prêts. Mais, il n'est
pas forcément le plus efficace.
### Le plus court d'abord
Le processus avec la plus petite suite d'instruction est exécuté en premier. Si deux processus ont le même nombre d'instructions,
on peut utiliser un algorithme FIFO pour déterminer le vainqueur. Il est performant, mais c'est compliqué de connaître
le nombre d'instructions.
Il nécessite d'éstimer en temps réel la longueur du processus.
$$\tau_{n+1} = \alpha\cdot t_{n}+(1-\alpha)\cdot \tau_{n}$$ <br>
$\tau_{n+1}$ : prochaine valeur estimée <br>
$\alpha$ : coefficient de pondération $0\leq\alpha\leq 1$ <br>
$t_{n}$ : valeur mesurée à l'instant $n$ <br>
$\tau_{n}$ précédente valeur estimée pour l'instant $n$ <br>
### Priorité
Cet algorithme donne au processeur le processus qui a la plus haute priorité qui est défini par l'utilisateur.
On peut rencontrer plusieurs problèmes :
- ***Blocage indéfini*** (indefinite blocking) : on reste bloqué dans un processus de haute priorité.
- ***Famine*** (starvation) : Les processus de basse priorité ne sont jamais exécuté.
***Solution*** : On augmente la priorité dum processus en attente tous les quantums de temps.
### Ordonnancement avec réquisition (preemptive)
On réévalue l'ordre des processus dans la queue à chaque tick et le processus élu prend ou garde le processeur.
### Tourniquet (round-robin)
Il est basé sur une tranche de temps fixe soit quantum de temps. On donne à chacun des processus ce temps et on passe au
processus suivant une fois le temps écoulé.
Lorsque le temps est grand, on retrouve en quelque sorte une FIFO, car le temps d'exécution des processus est plus court que
le quantum de temps.
Si le temps est très petit, le tourniquet est appelé **processeur partagé** (processor sharing).
<b><u>Overhead</u></b> : temps perdu pour changer de processus.<br>
### Files multiples (multi-queue)
On utilise cette technique lorsqu'on peut facilement classer les processus en différents groupes. Chaque queue possède son
propre algorithme d'ordonnancement. Un ordonnancement entre les queues est réalisé soit par priorité et réquisition, soit
en round robin.
### Files multiples imbriquées (multi-level feedback queue)
Cette technique permet aux processus d'évoluer dans des queues en fonction du temps d'exécution écoulé.
- Un processus entrant dans la queue des processus prêts est placé dans la queue 0
- Si le quantum est écoulé et que la suite d’instruction processeur n’est pas terminée, le processus est placé dans
la queue de priorité inférieure
Plus on descend dans les queues, plus on est de priorité basse.
<u>Exemple :</u> Plus on descend dans les queues, plus le quantum devient grand.
# Interblocage (DEADLOCK)
Un processus attend indéfiniment pour accéder à une ressource bloquée.
L'interblocage apparaît si les 4 conditions apparaissent simultanément :
1. ***L'exclusion mutuelle*** (mutual exclusion) : Une ressource au minimum n'est pas partageable.
2. ***La détention et l'attente*** (hold and wait) : Un processus qui dispose déjà d'au moins une ressource et qui attend l'acquisistion
d'une nouvelle ressource déjà utilisée par un autre processus.
3. ***Pas de réquisition*** (no preemption) : Les ressources obtenues par un processus ne peuvent pas lui être retirées contre son gré
4. ***L'attente circulaire*** (circulare wait) : 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.
Les interblocages peuvent être décrits plus précisément en utilsant un graphe appelé **graphe
d'allocation des ressources** (ressource allocation graph).
![interblocage.png](medias/interblocage.png)
- Si le graphe d'allocation des ressources ne contient aucun cycle $=>$ Aucun processus n'est en interblocage
- Si le graphe d'allocation des ressources contient un cycle $=>$ <u>Un risque</u> d'interblocage existe !!
On peut faire une réduction de graphe pour observer l'état suivant du graphe :
- Un graphe peut être réduit par un processus Pi, si le processus n'a pas de demande de ressource en cours.
- Pour faire une réduction, on enlève toutes les allocations du processus.
***Complètement réductible*** : si on arrive à faire des réductions successives jusqu'à ce qu'il n'y a plus de flêches
dans le graphe.
On peut résoudre le problème d'interblocage :
- ***Prévention*** : On garantit qu'aucun interblocage ne peut se produire.
- ***Prévenir** : Empêcher une des 4 conditions de se produire
- ***Éviter** : Éviter dynamiquement en allouant les ressource avec précaution
- ***Détection ou guérison*** : Lorsqu'un interblocage est détecté, on ramène le système dans un état où les processus sont débloqués
En cas d'interblocage, on peut utiliser deux algorithmes pour résoudre ce problème.
L'algorithme du banquier pour la prévention et ensuite un algorithme de reprise après interblocage.
L'algorithme de reprise fait soit appel à l'aide d'un opérateur, soit par une séquence automatique
qui tue les processus impliqués dans l'interblocage, soit un processus après l'autre jusqu'à ce que l'interblocage soit résolu.
Mais la destruction de processus est complexe et dangereuse.
## Algorithme du banquier (banker's algorithm)
Cette technique impose de connaître pour chaque processus les ressources dont il aura besoin.
- Il vérifie avant d'allouer une ressource que le graphe reste complètement réductible.
- Il alloue une ressource uniquement s'il y a plus de ressources disponibles que demandées.
- Sinon la demande de ressource est mise en attente.
<b><u>Exemple :</u></b><br>
![algo_banquier1.png](medias/algo_banquier1.png)
![algo_banquier2.png](medias/algo_banquier2.png)
Une ressource n'est attribuée que si les ressources demandées sont inférieurs aux ressources disponibles.
$$ (N)Needed < (A)Available $$
Si aucune rangée (processus) ne satisfait la condition, il y a <u><b>interblocage</b></u>.
+5
View File
@@ -23,6 +23,11 @@ les quantités sont modérées, le processeur est intensément utilisé, et ces
4. Souvent utilisé dans des applications où une flexibilité est nécessaire, mais peut poser des défis dans les systèmes où la prédictibilité est cruciale.
5. La gestion de l'incertitude et l'adaptabilité aux conditions changeantes sont des caractéristiques clés des systèmes non-déterministes.
### Système temps réel
- ***Temps réel dur:*** Le systéme fait une erreur si le délai est dépassé.
- ***Temps réel souple:*** Le système accepte le dépassement du délai sans grave conséquence.
- ***Temps réel ferme:*** Le système accepte le dépassement du délai, mais le résultat n'est plus d'aucune utilité.
### Management du temps (Timing)
Le timing peut avoir principalement deux formes différentes :
+2 -2
View File
@@ -4,7 +4,7 @@ Introduction aux systèmes d'exploitation
![operating_system.png](medias/operating_system.png)
Le système d'expoitation virtualise la partie hardward pour :
Le système d'exploitation virtualise la partie hardware pour :
- Simplifie l'utilisation
- Gère les ressources physiques
- Processeur
@@ -67,7 +67,7 @@ programme est exécuté afin d'optimiser l'utilisation du processeur.
La commutation de l'exécution d'un programme à un autre est assuré par l'**ordonnanceur** (scheduler).
*Inconvénients :* Les programmes cours, sont pénalisés car leur temps d'exécution dépend aussi des autres
*Inconvénients :* Les programmes cours, sont pénalisés, car leur temps d'exécution dépend aussi des autres
programmes en cours d'exécution.
Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB