Systèmes d'exploitation : trois éléments simples. Partie 2 : Abstraction : Processus (traduction)

Introduction aux systèmes d'exploitation

Hé Habr ! Je voudrais porter à votre attention une série d'articles-traductions d'une littérature intéressante à mon avis - OSTEP. Ce matériel traite assez en profondeur du travail des systèmes d'exploitation de type Unix, à savoir le travail avec les processus, divers planificateurs, la mémoire et d'autres composants similaires qui composent un système d'exploitation moderne. Vous pouvez voir l'original de tous les matériaux ici ici. Veuillez noter que la traduction a été faite de manière non professionnelle (assez librement), mais j'espère avoir conservé le sens général.

Les travaux de laboratoire sur ce sujet peuvent être trouvés ici:

Autres parties:

Vous pouvez également consulter ma chaîne sur télégramme =)

Examinons l'abstraction la plus fondamentale que le système d'exploitation fournit aux utilisateurs : le processus. La définition du processus est assez simple : programme en cours d'exécution. Le programme lui-même est un objet sans vie situé sur le disque : il s'agit d'un ensemble d'instructions et éventuellement de données statiques en attente d'être lancées. C'est le système d'exploitation qui prend ces octets et les exécute, transformant le programme en quelque chose d'utile.
Le plus souvent, les utilisateurs souhaitent exécuter plusieurs programmes en même temps. Par exemple, vous pouvez exécuter un navigateur, un jeu, un lecteur multimédia, un éditeur de texte, etc. sur votre ordinateur portable. En fait, un système typique peut exécuter des dizaines ou des centaines de processus simultanément. Ce fait rend le système plus facile à utiliser, vous n'avez jamais à vous soucier de savoir si le CPU est libre, vous exécutez simplement des programmes.

Cela pose le problème : comment donner l'illusion de plusieurs CPU ? Comment le système d’exploitation peut-il créer l’illusion d’un nombre presque infini de processeurs, même si vous ne disposez que d’un seul processeur physique ?

Le système d'exploitation crée cette illusion grâce à la virtualisation du processeur. En démarrant un processus, puis en l'arrêtant, en démarrant un autre processus, etc., le système d'exploitation peut entretenir l'illusion qu'il existe de nombreux processeurs virtuels, alors qu'en réalité il y aura un ou plusieurs processeurs physiques. Cette technique est appelée division des ressources CPU par temps. Cette technique permet aux utilisateurs d'exécuter autant de processus simultanés qu'ils le souhaitent. Le coût de cette solution est la performance : si le CPU est partagé par plusieurs processus, chaque processus sera traité plus lentement.
Pour implémenter la virtualisation du processeur, et surtout pour bien le faire, le système d'exploitation a besoin d'un support à la fois de bas niveau et de haut niveau. Le support de bas niveau est appelé mécanismes sont des méthodes ou des protocoles de bas niveau qui implémentent la partie requise de la fonctionnalité. Un exemple d'une telle fonctionnalité est le changement de contexte, qui donne au système d'exploitation la possibilité d'arrêter un programme et d'exécuter un autre programme sur le processeur. Cette division temporelle est implémentée dans tous les systèmes d'exploitation modernes.
Au-dessus de ces mécanismes se trouve une certaine logique intégrée au système d’exploitation, sous la forme de « politiques ». Politique est un certain algorithme de prise de décision pour le système d'exploitation. De telles politiques, par exemple, décident quel programme doit être lancé (à partir d'une liste de commandes) en premier. Ainsi, par exemple, ce problème sera résolu par une politique appelée planificateur (politique de planification) et lors du choix d'une solution, il sera guidé par des données telles que : l'historique de démarrage (quel programme a été lancé le plus longtemps au cours des dernières minutes), quelle charge supporte ce processus (quels types de programmes ont été lancés), les mesures de performances (si le système est optimisé pour l'interaction interactive ou pour le débit ) et ainsi de suite.

Abstraction : processus

L'abstraction d'un programme en cours d'exécution exécuté par le système d'exploitation est ce que nous appelons processus. Comme mentionné précédemment, un processus est simplement un programme en cours d’exécution, à n’importe quelle période de temps instantanée. Un programme avec lequel nous pouvons obtenir des informations récapitulatives de diverses ressources système auxquelles ce programme accède ou affecte lors de son exécution.
Pour comprendre les composants du processus, vous devez comprendre les états du système : ce que le programme peut lire ou modifier pendant son fonctionnement. À tout moment, vous devez comprendre quels éléments du système sont importants pour l’exécution du programme.
L’un des éléments évidents de l’état du système inclus dans le processus est mémoire. Les instructions sont situées en mémoire. Les données que le programme lit ou écrit se trouvent également en mémoire. Ainsi, la mémoire qu’un processus peut adresser (appelée espace d’adressage) fait partie du processus.
Les registres font également partie de l'état du système. De nombreuses instructions visent à modifier la valeur des registres ou à lire leur valeur, et les registres deviennent donc également une partie importante du fonctionnement du processus.
Il convient de noter que l’état de la machine est également constitué de certains registres spéciaux. Par exemple, IP - pointeur d'instruction — un pointeur vers l'instruction que le programme est en cours d'exécution. Il y a aussi pointeur de pile et lié à cela pointeur de cadre, qui permettent de gérer : les paramètres des fonctions, les variables locales et les adresses de retour.
Enfin, les programmes accèdent souvent à la ROM (mémoire morte). Ces informations « E/S » (entrée/sortie) doivent inclure une liste des fichiers actuellement ouverts par le processus.

API de processus

Afin d'améliorer notre compréhension du fonctionnement du processus, étudions des exemples d'appels système qui devraient être inclus dans toute interface de système d'exploitation. Ces API sont disponibles sous une forme ou une autre sur n'importe quel système d'exploitation.

Création (création) : le système d'exploitation doit inclure une méthode qui vous permet de créer de nouveaux processus. Lorsque vous saisissez une commande dans le terminal ou lancez une application en double-cliquant sur une icône, un appel est envoyé au système d'exploitation pour créer un nouveau processus puis lancer le programme spécifié.
Enlèvement: Puisqu'il existe une interface pour créer un processus, le système d'exploitation devrait également offrir la possibilité de forcer la suppression d'un processus. La plupart des programmes démarrent et se terminent naturellement d'eux-mêmes au fur et à mesure de leur exécution. Sinon l'utilisateur aimerait pouvoir les tuer et donc une interface pour arrêter le processus serait utile.
Attendez (en attente) : Parfois, il est utile d'attendre la fin d'un processus, c'est pourquoi certaines interfaces sont fournies pour offrir la possibilité d'attendre.
Divers contrôles (contrôles divers) : En plus de tuer et d'attendre le processus, il existe également d'autres méthodes de contrôle diverses. Par exemple, la plupart des systèmes d'exploitation offrent la possibilité de geler un processus (arrêter son exécution pendant une certaine période) puis de le reprendre (poursuivre l'exécution)
Statut (état) : Il existe différentes interfaces pour obtenir des informations sur l'état d'un processus, telles que la durée de son exécution ou l'état dans lequel il se trouve actuellement.

Systèmes d'exploitation : trois éléments simples. Partie 2 : Abstraction : Processus (traduction)

Création de processus : détails

L’une des choses intéressantes est de savoir exactement comment les programmes sont transformés en processus. Surtout comment le système d'exploitation récupère et exécute le programme. Comment exactement le processus est créé.
Tout d'abord, le système d'exploitation doit charger le code du programme et les données statiques en mémoire (dans l'espace d'adressage du processus). Les programmes se trouvent généralement sur un disque ou un lecteur SSD dans un format exécutable. Ainsi, le processus de chargement du programme et des données statiques en mémoire nécessite que le système d'exploitation soit capable de lire ces octets du disque et de les placer quelque part en mémoire.

Dans les premiers systèmes d'exploitation, le processus de chargement était effectué avec impatience, ce qui signifie que l'intégralité du code était chargée en mémoire avant le lancement du programme. Les systèmes d'exploitation modernes le font paresseusement, c'est-à-dire qu'ils chargent des morceaux de code ou des données uniquement lorsque le programme en a besoin lors de son exécution.

Une fois le code et les données statiques chargés dans la mémoire du système d’exploitation, quelques tâches supplémentaires doivent être effectuées avant que le processus puisse s’exécuter. Une certaine quantité de mémoire doit être allouée à la pile. Les programmes utilisent la pile pour les variables locales, les paramètres de fonction et les adresses de retour. Le système d'exploitation alloue cette mémoire et la donne au processus. La pile peut également être allouée avec certains arguments, notamment elle remplit les paramètres de la fonction main(), par exemple avec un tableau d'argc et d'argv.

Le système d'exploitation peut également allouer de la mémoire au tas de programme. Le tas est utilisé par les programmes pour demander explicitement des données allouées dynamiquement. Les programmes demandent cet espace en appelant la fonction malloc () et l'efface explicitement en appelant la fonction libre(). Le tas est nécessaire pour les structures de données telles que les feuilles liées, les tables de hachage, les arbres et autres. Au début, une petite quantité de mémoire est allouée au tas, mais au fil du temps, à mesure que le programme s'exécute, le tas peut demander plus de mémoire via l'appel API de la bibliothèque malloc(). Le système d'exploitation est impliqué dans le processus d'allocation de mémoire supplémentaire pour aider à satisfaire ces appels.

Le système d'exploitation effectuera également des tâches d'initialisation, notamment celles liées aux E/S. Par exemple, sur les systèmes UNIX, chaque processus dispose par défaut de 3 descripteurs de fichiers ouverts, pour l'entrée, la sortie et l'erreur standard. Ces poignées permettent aux programmes de lire les entrées du terminal ainsi que d'afficher des informations à l'écran.

Ainsi, en chargeant du code et des données statiques en mémoire, en créant et en initialisant la pile et en effectuant d'autres travaux liés à l'exécution des tâches d'E/S, le système d'exploitation prépare l'étape d'exécution du processus. Enfin, il reste une dernière tâche : exécuter le programme via son point d’entrée, appelé fonction main(). En exécutant la fonction main(), le système d'exploitation transfère le contrôle du processeur au processus nouvellement créé, le programme commence ainsi à s'exécuter.

État du processus

Maintenant que nous comprenons ce qu'est un processus et comment il est créé, énumérons les états de processus dans lesquels il peut se trouver. Dans sa forme la plus simple, un processus peut se trouver dans l'un de ces états :
Fonctionnement. Lors de l'exécution, le processus s'exécute sur le processeur. Cela signifie que les instructions sont en cours d'exécution.
Prêt à fonctionner. À l'état prêt, le processus est prêt à être exécuté, mais pour une raison quelconque, le système d'exploitation ne l'exécute pas à l'heure spécifiée.
Bloqué. Dans l'état bloqué, un processus effectue certaines opérations qui l'empêchent d'être prêt à s'exécuter jusqu'à ce qu'un événement se produise. Un exemple courant est lorsqu'un processus lance une opération d'E/S, il est bloqué afin qu'un autre processus puisse utiliser le processeur.

Systèmes d'exploitation : trois éléments simples. Partie 2 : Abstraction : Processus (traduction)

Vous pouvez imaginer ces états sous la forme d’un graphique. Comme nous pouvons le voir sur l'image, l'état du processus peut changer entre RUNNING et READY à la discrétion du système d'exploitation. Lorsque l'état d'un processus passe de PRÊT à RUNNING, cela signifie que le processus a été planifié. Dans la direction opposée - supprimé du tracé. Au moment où un processus devient BLOQUÉ, par exemple, j'initie une opération IO, le système d'exploitation le maintiendra dans cet état jusqu'à ce qu'un événement se produise, par exemple la fin de l'IO. à ce moment le passage à l'état READY et éventuellement immédiatement à l'état RUNNING si l'OS le décide.
Examinons un exemple de la manière dont deux processus traversent ces états. Pour commencer, imaginons que les deux processus sont en cours d’exécution et que chacun utilise uniquement le processeur. Dans ce cas, leurs états ressembleront à ceci.

Systèmes d'exploitation : trois éléments simples. Partie 2 : Abstraction : Processus (traduction)

Dans l'exemple suivant, le premier processus, après un certain temps d'exécution, demande IO et entre dans l'état BLOCKED, permettant à un autre processus de s'exécuter (FIG 1.4). Le système d'exploitation voit que le processus 0 n'utilise pas le processeur et démarre le processus 1. Pendant que le processus 1 est en cours d'exécution, IO est terminé et l'état du processus 0 passe à READY. Enfin, le processus 1 est terminé et, une fois terminé, le processus 0 démarre, exécute et termine son travail.

Systèmes d'exploitation : trois éléments simples. Partie 2 : Abstraction : Processus (traduction)

Structure de données

Le système d'exploitation lui-même est un programme et, comme tout autre programme, il possède des structures de données clés qui permettent de suivre diverses informations pertinentes. Pour suivre l'état de chaque processus, le système d'exploitation prendra en charge certains liste des processus pour tous les processus à l'état PRÊT et quelques informations supplémentaires pour suivre les processus en cours d'exécution. En outre, le système d'exploitation doit surveiller les processus bloqués. Une fois les E/S terminées, le système d'exploitation doit réveiller le processus requis et le mettre dans un état prêt à être exécuté.

Par exemple, le système d'exploitation doit conserver l'état des registres du processeur. Au moment où le processus s'arrête, l'état des registres est stocké dans l'espace d'adressage du processus, et au moment où son fonctionnement se poursuit, les valeurs des registres sont restaurées et continuent ainsi l'exécution de ce processus.

En plus des états prêt, bloqué et en cours d'exécution, il existe d'autres états. Parfois, au moment de la création, un processus peut être à l'état INIT. Enfin, un processus peut être placé dans l'état FINAL lorsqu'il est déjà terminé, mais que ses informations n'ont pas encore été effacées. Sur les systèmes UNIX, cet état est appelé processus zombie. Cet état est utile dans les cas où un processus parent souhaite connaître le code retour d'un enfant, par exemple, généralement 0 signale un succès et 1 une erreur, mais les programmeurs peuvent émettre des codes de sortie supplémentaires pour signaler différents problèmes. Lorsque le processus parent se termine, il effectue un dernier appel système, tel que wait(), pour attendre la fin du processus enfant et signaler au système d'exploitation qu'il peut effacer toutes les données associées au processus terminé.

Systèmes d'exploitation : trois éléments simples. Partie 2 : Abstraction : Processus (traduction)

Points clés de la conférence :

Processus - l'abstraction principale d'un programme en cours d'exécution dans le système d'exploitation. À tout moment, un processus peut être décrit par son état : le contenu de la mémoire dans son espace d'adressage, le contenu des registres du processeur, y compris le pointeur d'instruction et le pointeur de pile, et les informations d'E/S, telles que les fichiers ouverts en cours de lecture ou d'écriture.
API de processus se compose d’appels que les programmes peuvent effectuer aux processus. Il s'agit généralement d'appels de création, de suppression ou d'autres appels.
● Le processus se trouve dans l'un des nombreux états suivants : en cours d'exécution, prêt ou bloqué. Divers événements tels que la planification, les exceptions à la planification ou les attentes peuvent modifier l'état d'un processus de l'un à l'autre.
Liste des processus contient des informations sur tous les processus du système. Chaque entrée est appelée bloc de contrôle de processus, qui est en réalité une structure contenant toutes les informations nécessaires sur un processus spécifique. 

Source: habr.com

Ajouter un commentaire