diff --git a/index.html b/index.html index 67ede74..9226f48 100644 --- a/index.html +++ b/index.html @@ -164,6 +164,7 @@ + diff --git a/infotro/PTR/PCO.md b/infotro/PTR/PCO.md new file mode 100644 index 0000000..3fdffaa --- /dev/null +++ b/infotro/PTR/PCO.md @@ -0,0 +1,240 @@ +

+Programmation concurrente +

+ +Un programme concurrent est un programme non séquentiel. +Soit l'expression arithmétique suivante : $(a+b) * (c+d)$. + +***Programmation séquentiel*** +1. $x = (a+b)$ +2. $y = (c+d)$ +3. $x*y$ + +***Programmation concurrente*** +1. $x = (a+b) \qquad y = (c+d)$ +2. $x*y$ + +La programmation concurrente sur 1 CPU permet d'exploiter pleinement les périphériques parallèlement au processeur. +Cela permet d'éviter de bloquer toutes les applications lorsqu'une seule est en attente d'une réponse. + +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 + +Les processus ne sont jamais totalement indépendants. +Ils partagent des ressources (mémoire, fichiers, périphériques, variable, etc.) + +Ceci peut conduire à des erreurs et doit donc être controlé. + +- ***Section critique :*** partie du code qui accède à une ressource partagée. +- ***Exclusion mutuelle :*** un seul processus à la fois peut accéder à la section critique. +- ***Ressource critique :*** ressource qui doit être accédé en exclusion mutuelle + +On pourrait éviter les problèmes d'exclusion mutuelle si on pouvait assurer que deux processus n'exécute jamais en même temps une section +critique. +On peut résoudre ce problème à l'aide de **mutex** ou **sémaphore**. + +## Exclusion mutuelle par attente active + +```pascal +type processNum = 1..2; + +module CS; /* Section critique */ + defines Enter, Leave; /* Primitive */ + + var + request : array processNum of boolean; + tour : processNum; + procedure Enter(num: processNum); + begin + request[num] := true; /* Demande d'accès */ + tour := 3 – num; /* Autre processus */ + repeat + /* Attendre que l'autre processus ait fini avec "not request" */ + /* Priorité si les deux processus demandent en même temps à la section critique + grâce à "tour = num" */ + until (not request[3-num]) or (tour = num) + end Enter; + + procedure Leave(num: processNum); + begin + request[num] := false + end Leave; + + begin /* Initialisation */ + request[1] := false; + request[2] := false + end CS; + +/***********************************************************************/ + +process P1; + uses CS, Console; +begin + CS.Enter(1); + Console.Write(”Error on hard disk !”); + CS.Leave(1); +end P1; + +/***********************************************************************/ + +process P2; + uses CS, Console; +begin + CS.Enter(2); + Console.Write(”Printer not ready !”); + CS.Leave(2); +end P2; +``` + +- si les processus *P1* et *P2* ne tentent pas de pénétrer simultanément dans la section + critique, la variable *request[3-num]* est fausse et l'entrée en section critique est + autorisée +- si par contre les processus *P1* et *P2* tentent de pénétrer simultanément dans la section + critique, la variable *tour* permet d'arbitrer entre les deux demandes. La variable + *tour* (à la ligne 15) indique le numéro du processus élu + +Cette méthode peut facilement être généralisée à n processus. Il suffit de faire *tour := n+1 – num* et +*request[n+1-num]*. + +Cette solution n'est pas satisfaisante, car elle consomme beaucoup de ressources CPU. En effet, un processus +qui attend l'accès à la section critique est en attente active. Il est donc en boucle constante et consomme +beaucoup de ressources CPU. + + +## Exclusion mutuelle par masquage des interruptions +Masquer les interruptions pour résoudre le problème de l'exclusion mutuelle. +Plus d'interruption $=>$ plus de commutation de processus $=>$ plus de risque de violer l'exclusion mutuelle. + +Le danger avec cette solution est le risque de perte d'information provenant des périphériques. Cela ne peut être une bonne solution +que si la section critique est très courte. Il est dangereux de laisser la possibilité de masquer les interruptions à l'utilisateur. + + +## Instruction TAS (TestAndSet) +L'exclusion mutuelle par masquage des interruptions n'est pas possible dans une architecture multiprocesseur. +Il est possible de résoudre le problème de l'exclusion mutuelle en utilisant l'instruction *TAS*. +Elle permet de tester et de modifier une variable en **une seule instruction** assembleur. + + +# Mutex +Le mutex est utilisé pour bloquer l'accès simultané aux sections critiques avec les primitives suivantes : +- ***block() :*** Il laisse passer un seul processus à la fois. Si la section est déjà bloquée, le processus et mis dans +une file d'attente. +```pascal +procedure Block(var v:lock); +begin + if v.state = OPEN then + v.state := CLOSE + else + block the process in the list "v.waiting" + end if +end Block; +} +``` +- ***release() :*** Il libère la section critique, si la file d'attente est vide. Sinon, il passe la main au processus +suivant. +```pascal +procedure Release(var v:lock); +begin + if queue "v.waiting" not empty then + unblock first process in the list "v.waiting" + else + v.state := OPEN + end if +end Release; +} +``` +Ces procédures sont elles même des sections critiques. Elles sont cepandant très courte et ne contiennent aucunes entrées-sorties. +Elles peuvent donc être implémentées à l'aide d'une [Exclusion mutuelle par masquage des interruptions](#exclusion-mutuelle-par-masquage-des-interruptions) +ou d'une [instruction TAS](#instruction-tas-testandset). + +Les Mutex restent un outil primitif. Ils ne s'appliquent pas sur des problèmes plus complexes. + +# Sémaphore +Le sémaphore est une généralisation du mutex. Il permet de bloquer l'accès à une ressource partagée par plusieurs processus. +Il limite l'accès à plusieurs même ressources utilisées par plusieurs processus. + +Par exemple : les processus ont besoin d'imprimer et il y a plusieurs imprimantes à disposition. +Le sémaphore va limiter l'accès au nombre d'imprimantes disponibles. + +Les primitives de sémaphores sont : +- ***P*** (Passeren = passer) appelé aussi *wait*, *up*, *get* ou *lock* +```pascal +procedure P(var s:semaphore); +begin + s.num := s.num – 1; + if s.num < 0 then + block the process at the end of the list "s.waiting" + end if +end P; +``` +- ***V*** (Vrijgeven = libérer) appelé aussi *signal*, *down*, *release* ou *unlock* +```pascal +procedure V(var s:semaphore); +begin + s.num := s.num + 1; + if s.num <= 0 then + unblock first process in the list "s.waiting" + end if +end V; +``` + +À l'initialisation, le sémaphore est initialisé au nombre de mêmes ressources disponibles. +Ou alors, il est initialisé à 1 pour un mutex. +Ou alors, il est initialisé à 0 pour un sémaphore binaire (file d'attente). + + +## Interblocage +L'interblocage est un problème qui peut survenir lorsqu'un ensemble de processus se bloquent mutuellement. +On appelle aussi cela un **DEADLOCK**. + +## Résolution reader / writter +Le but est qu'il peut avoir plusieurs processus qui puisse lire la même ressource et aucun modifier la ressource. +Sinon, **un** processus peut modifier la ressource et aucun peut lire. +```cpp +void BeginRead(void) { + osSemaphoreAcquire(rw, osWaitForever); + osSemaphoreAcquire(mutexNbReader, osWaitForever); // ENTER CRITICAL SECTION + nbReader++; + if(nbReader == 1) osSemaphoreAcquire(w, osWaitForever); + osSemaphoreRelease(mutexNbReader); // EXIT CRITICAL SECTION + osSemaphoreRelease(rw); +} + +void EndRead(void) { + osSemaphoreAcquire(mutexNbReader, osWaitForever); // ENTER CRITICAL SECTION + nbReader--; + if(nbReader == 0) osSemaphoreRelease(w); + osSemaphoreRelease(mutexNbReader); // EXIT CRITICAL SECTION +} + +void BeginWrite(void) { + osSemaphoreAcquire(rw, osWaitForever); + osSemaphoreAcquire(w, osWaitForever); +} + +void EndWrite(void) { + osSemaphoreRelease(w); + osSemaphoreRelease(rw); +} +``` + + + + +# Synchronisation + + +Etat d'un processus : + +![img_1.png](img_1.png) + +Le processeur possède une liste de descripteur caractérisant chaque processus. Ces descripteurs de processus qui +contiennent le registre de status et un pointeur sur sa stack. Ils sont utilisé pour faire des switching context : +1. Le noyau va sauvegarder les registres de travail du processus en cours sur la stack. +2. Il va sauvegarder aussi le registre de status et le pointeur de stack dans la liste de descripteurs. +3. Il va prendre le descripteur du prochain processus et utiliser ses registres. +4. Le processus continue jusqu'au nouveau switching context. + diff --git a/infotro/PTR/README.md b/infotro/PTR/README.md index 42e52cc..104f26f 100644 --- a/infotro/PTR/README.md +++ b/infotro/PTR/README.md @@ -4,4 +4,6 @@ PTR - Programmation Temps Réel - [XF](/infotro/PTR/XF.md) - [UML](/infotro/PTR/UML) -- [RealTime](/infotro/PTR/RealTime) \ No newline at end of file +- [RealTime](/infotro/PTR/RealTime) +- [SYS - Systèmes](/infotro/PTR/SYS) +- [PCO - Programmation Concurrente](/infotro/PTR/PCO) \ No newline at end of file diff --git a/infotro/PTR/SYS.md b/infotro/PTR/SYS.md new file mode 100644 index 0000000..103f013 --- /dev/null +++ b/infotro/PTR/SYS.md @@ -0,0 +1,163 @@ +

+Introduction aux systèmes d'exploitation +

+ +![operating_system.png](medias/operating_system.png) + +Le système d'expoitation virtualise la partie hardward pour : +- Simplifie l'utilisation +- Gère les ressources physiques + - Processeur + - Mémoire principale + - Entrées-sorties (disques, interfaces réseaux, ...) + +L'OS gère les ressources à l'aide de technique de gestion des mémoires et de partage de ressources +partageable entre plusieurs utilisateurs (ex : threads). +Pour ce faire, il +- connait à tout moment l'utilisateur d'une ressource +- gère les accès à une ressource +- accorde l'usage d'une ressource +- évite les conflits + +Les premiers systèmes d'exploitation étaient des systèmes à traitement par lots. +Les programmes étaient regroupés en lots et exécutés les uns après les autres. +Les programmes étaient chargés en mémoire et exécutés sans intervention de l'utilisateur. + +## Machine à transistors + +- Coûtent cher +- Les utilisateurs ne peuvent pas interagir avec le système +- Les utilisateurs écrivent leurs programmes en Fortran et en assembleur + +Fonctionnement : +1. Programmation d'une carte perforée en Fortran ou en assembleur +2. L'opérateur prend les cartes perforées et les charge dans le compilateur +3. L'opérateur récupère les cartes perforées compilées et les charge dans "l'ordinateur" +4. L'ordinateur exécute le programme +5. S'il y a une erreur, l'opérateur imprime l'image de la mémoire sur un listing et doit tout recommencer. + +## Systèmes à traitement par lots +Pour accélérer les opérations, deux méthodes sont utilisées : +- ***Le traitement par lots (batch processing) :*** Regroupe et traite à la suite les travaux similaires +- ***Le moniteurs d'enchaînement (linking monitor) :*** Les travaux sont automatiquement enchaîné et +executé par un programme spécialisé (ancêtre des systèmes d'exploitation) + - Une place mémoire lui est réservée dans la mémoire centrale qui se divise donc en une zone moniteur + et une zone utilisateur + +## Sysèmes avec spooling +Les systèmes avec spooling permettent d'accéder simultanément à plusieurs périphériques d'entrée/sortie. +Les travaux sont stockés dans une file d'attente (spool) et sont traités par un programme spécialisé. +Le spooling permet de traiter plusieurs travaux en même temps. + +La mémoire est partagée en quatre programmes : +- Le programme d'entrée +- Le programme d'enchaînement +- Le programme de l'utilisateur +- Le programme de sortie + +![spooling.png](medias/spooling.png) + +## Système à multi-programmation +La multi-programmation permet de partager le processeur entre plusieurs programmes. +Chaque programme est chargé en mémoire et est exécuté en alternance. +Dès qu'un programme doit lire des données ou écrire des résultats, il est mis en attente et un autre +programme est exécuté afin d'optimiser l'utilisation du processeur. + +![multiprogramming .png](medias/multiprogramming.png) + +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 +programmes en cours d'exécution. + + +## Système à temps partagé +Le système à temps partagé permet à plusieurs utilisateurs d'accéder simultanément à l'ordinateur. +Chaque utilisateur dispose d'un temps d'utilisation du processeur (time slice) qui est très court (ex. 40 msec). + +![time-sharing.png](medias/time-sharing.png) + +## Système temps réel +Les systèmes temps réel doivent être capables réagire au rythme où les données arrivent et repartent. +Ils ont des contraîntes plus hautes ques les systèmes à temps partagé, qui peuvent se permettent d'attendre +alors qu'un système temps réel aurait des conséquences fâcheuses. + +## Systèmes multi-processeur répartis +Dans un système multi-processeur répartis, chaque processeur dispose de son propre système d'exploitation. +Les systèmes d'exploitation communiquent entre eux pour partager les ressources. + + +# Mécanisme d'entrées-sorties +Pour accéder aux périphériques, le processeur utilise des mécanismes d'entrées sorties. + +## Les registres d'un processeur +Les registres contenus dans le processeur sont regroupés selon leur fonctionnalités +- Registre généraux +- Registre spécialisés + - Le **registre d'instruction** IR (Instruction Register) contient l'instruction courante + - Le **compteur ordinal** PC (Program Counter) contient l'adresse de l'instruction courante +- Le **registre d'état** SR (Status Register) contient des informations sur l'état du processeur + +Ces regstres caractérisent le contexte d'un programme. Il s'agit de la partie sauvegardée lors d'un +*switching context* (changement de contexte). + + +## Les registres d'un périphérique +Les périphériques disposent, pour comuniquer avec le processeur, d'un certain nombre de registres: +- **Registre de données** DR (Data Register) : Contient les données à lire ou à écrire +- **Registre d'état** SR (Status Register) : Contient des informations sur l'état du périphérique +- **Registre de commande** CR (Command Register) : Détermine les caractéristiques du périphérique + +## Entrées-sorties en boucle d'attente +Dans ce mode, le processeur attend que le périphérique soit prêt pour effectuer une opération. +Le processeur effectue une boucle d'attente jusqu'à ce que le périphérique soit prêt. + +1. Le processeur contrôle le registre d'état du périphérique +2. Si le périphérique n'est pas prêt, le processeur effectue une boucle d'attente. S'il est prêt : +3. Le processeur écrit les données dans le registre de données +4. Le processeur écrit la commande dans le registre de commande +5. Le périphérique effectue l'opération +6. Le périphérique met à jour le registre d'état +7. Le processeur lit les données dans le registre de données + +Si le périphérique notifie le processeur : +1. Le périphérique va changer son statut +2. Le processeur va pouvoir aller chercher les données dans le registre de données + +## Les interruptions +Les interruptions permettent de signaler au processeur qu'un événement s'est produit. +Le signal est la conséquence d'un évènement interne au programme et résultant de son exécution ou +externe et indépendant de son exécution. Toute l'information nécessaire pour traiter l'interruption +est regroupé en mémoire dans deux mots consécutis, appelés **vecteur d'interruption** (vector interrupt). +On y trouve : +- L'adresse de la routine de traitement de l'interruption +- Le registre d'état du processeur pour cette routine. + +Lorsqu'une interruption se produit, le processeur effectue un switching context et exécute la routine. + +On distingue en général au moins trois niveaux d'interruption : +- Les interruptions externes +- Les exceptions internes +- Les appels systèmes + +![interruptions.png](medias/interruptions.png) + +## La DMA +La [DMA](/infotro/SEm/DMA) (Direct Access Memory) permet de faire des transferts vers la mémoire rapidement. +Le processeur laisse le controller DMA accéder au périphérique pour amener les données directement dans la +mémoire et éviter de perdre du temps en passant par le processeur qui doit faire une copie des données. +Elle est très utile lorsqu'il y a un grand nombre de données. + + + + + + + + + + + + + + diff --git a/infotro/PTR/UML.md b/infotro/PTR/UML.md index e511583..24fd944 100644 --- a/infotro/PTR/UML.md +++ b/infotro/PTR/UML.md @@ -5,6 +5,13 @@ UML ## Class ### Association bidirectionnel +```mermaid +%%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%% +classDiagram +direction LR +A -- B +``` + ```plantuml @startuml A - B : " " @@ -98,7 +105,26 @@ vt is Infection @enduml ``` + ## Sequence +```mermaid +%%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%% +sequenceDiagram + participant a as A + participant b as B + a ->> b: synchrone / call + a -) b: asynchrone + activate b + b -->> a: replay + deactivate b + + + b ->> b: sync auto call + + b -) b: async auto call + +``` + ```plantuml @startuml participant A as a diff --git a/infotro/PTR/img.png b/infotro/PTR/img.png new file mode 100644 index 0000000..8d40427 Binary files /dev/null and b/infotro/PTR/img.png differ diff --git a/infotro/PTR/img_1.png b/infotro/PTR/img_1.png new file mode 100644 index 0000000..2f2fd70 Binary files /dev/null and b/infotro/PTR/img_1.png differ diff --git a/infotro/PTR/medias/interruptions.png b/infotro/PTR/medias/interruptions.png new file mode 100644 index 0000000..4b03815 Binary files /dev/null and b/infotro/PTR/medias/interruptions.png differ diff --git a/infotro/PTR/medias/multiprogramming.png b/infotro/PTR/medias/multiprogramming.png new file mode 100644 index 0000000..881f3a2 Binary files /dev/null and b/infotro/PTR/medias/multiprogramming.png differ diff --git a/infotro/PTR/medias/operating_system.png b/infotro/PTR/medias/operating_system.png new file mode 100644 index 0000000..9b32ebb Binary files /dev/null and b/infotro/PTR/medias/operating_system.png differ diff --git a/infotro/PTR/medias/spooling.png b/infotro/PTR/medias/spooling.png new file mode 100644 index 0000000..c9b27a7 Binary files /dev/null and b/infotro/PTR/medias/spooling.png differ diff --git a/infotro/PTR/medias/time-sharing.png b/infotro/PTR/medias/time-sharing.png new file mode 100644 index 0000000..2d1d930 Binary files /dev/null and b/infotro/PTR/medias/time-sharing.png differ diff --git a/infotro/README.md b/infotro/README.md index e36ffe0..8fc7b3b 100644 --- a/infotro/README.md +++ b/infotro/README.md @@ -4,6 +4,8 @@ - [XF](/infotro/PTR/XF.md) - [UML](/infotro/PTR/UML) - [RealTime](/infotro/PTR/RealTime) +- [SYS - Systèmes](/infotro/PTR/SYS) +- [PCO - Programmation Concurrente](/infotro/PTR/PCO) ## [SDi - Système Distribué](/infotro/SDi/) diff --git a/infotro/_navbar.md b/infotro/_navbar.md index cb0978e..8f0eb82 100644 --- a/infotro/_navbar.md +++ b/infotro/_navbar.md @@ -2,6 +2,8 @@ * [XF](/infotro/PTR/XF) * [UML](/infotro/PTR/UML) * [RealTime](/infotro/PTR/RealTime) + * [SYS - Systèmes](/infotro/PTR/SYS) + * [PCO - Programmation Concurrente](/infotro/PTR/PCO) * [SDi - Systèmes Distribués](/infotro/SDi) * [Transmission process](/infotro/SDi/transmission_process.md) * [IOT Technologies](/infotro/SDi/iot_technologies.md)