Systèmes d'exploitation : trois éléments simples. Partie 3 : API de 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 =)

Alarme! Il y a un laboratoire pour cette conférence ! Regarder github

API de processus

Regardons un exemple de création d'un processus dans un système UNIX. Cela se produit via deux appels système fourchette() и exécutable().

Fourchette d'appel()

Systèmes d'exploitation : trois éléments simples. Partie 3 : API de processus (traduction)

Considérons un programme qui effectue un appel fork(). Le résultat de son exécution sera le suivant.

Systèmes d'exploitation : trois éléments simples. Partie 3 : API de processus (traduction)

Tout d’abord, nous entrons dans la fonction main() et imprimons la chaîne à l’écran. La ligne contient l'identifiant du processus qui dans l'original est appelé PID ou identifiant de processus. Cet identifiant est utilisé sous UNIX pour faire référence à un processus. La commande suivante appellera fork(). À ce stade, une copie presque exacte du processus est créée. Pour le système d'exploitation, il semble qu'il y ait 2 copies du même programme en cours d'exécution sur le système, qui à leur tour quitteront la fonction fork(). Le processus enfant nouvellement créé (par rapport au processus parent qui l'a créé) ne sera plus exécuté, à partir de la fonction main(). Il ne faut pas oublier qu'un processus enfant n'est pas une copie exacte du processus parent ; en particulier, il possède son propre espace d'adressage, ses propres registres, son propre pointeur vers des instructions exécutables, etc. Ainsi, la valeur renvoyée à l’appelant de la fonction fork() sera différente. En particulier, le processus parent recevra en retour la valeur PID du processus enfant, et l'enfant recevra une valeur égale à 0. Grâce à ces codes retour, vous pourrez alors séparer les processus et forcer chacun d'eux à faire son propre travail. . Cependant, l'exécution de ce programme n'est pas strictement définie. Après avoir été divisé en 2 processus, le système d'exploitation commence à les surveiller et à planifier leur travail. S'il est exécuté sur un processeur monocœur, l'un des processus, dans ce cas le parent, continuera à fonctionner, puis le processus enfant recevra le contrôle. Au redémarrage, la situation peut être différente.

Appel en attente()

Systèmes d'exploitation : trois éléments simples. Partie 3 : API de processus (traduction)

Considérez le programme suivant. Dans ce programme, en raison de la présence d'un appel attendre() Le processus parent attendra toujours la fin du processus enfant. Dans ce cas, nous obtiendrons une sortie de texte strictement définie à l'écran

Systèmes d'exploitation : trois éléments simples. Partie 3 : API de processus (traduction)

appel exec()

Systèmes d'exploitation : trois éléments simples. Partie 3 : API de processus (traduction)

Considérez le défi exécutable(). Cet appel système est utile lorsque nous voulons exécuter un programme complètement différent. Ici, nous appellerons execvp() pour exécuter le programme wc qui est un programme de comptage de mots. Que se passe-t-il lorsque exec() est appelé ? Cet appel reçoit le nom du fichier exécutable et certains paramètres comme arguments. Après quoi le code et les données statiques de ce fichier exécutable sont chargés et son propre segment avec le code est écrasé. Les zones de mémoire restantes, telles que la pile et le tas, sont réinitialisées. Après quoi, le système d'exploitation exécute simplement le programme en lui transmettant un ensemble d'arguments. Nous n'avons donc pas créé de nouveau processus, nous avons simplement transformé le programme en cours d'exécution en un autre programme en cours d'exécution. Après avoir exécuté l'appel exec() dans le descendant, il semble que le programme d'origine ne s'exécute pas du tout.

Cette complication de démarrage est tout à fait normale pour un shell Unix et permet à ce shell d'exécuter du code après avoir appelé fourchette(), mais avant l'appel exécutable(). Un exemple d'un tel code serait d'ajuster l'environnement shell aux besoins du programme en cours de lancement, avant de le lancer.

coquillage - juste un programme utilisateur. Elle vous montre la ligne d'invitation et attend que vous y écriviez quelque chose. Dans la plupart des cas, si vous écrivez le nom d'un programme ici, le shell trouvera son emplacement, appellera la méthode fork(), puis appellera un type d'exec() pour créer un nouveau processus et attendra qu'il se termine à l'aide d'un appel wait(). Lorsque le processus enfant se termine, le shell reviendra de l'appel wait(), imprimera à nouveau l'invite et attendra que la commande suivante soit entrée.

La division fork() & exec() permet au shell de faire les choses suivantes, par exemple :
fichier wc > nouveau_fichier.

Dans cet exemple, la sortie du programme wc est redirigée vers un fichier. La façon dont le shell y parvient est assez simple : en créant un processus enfant avant d'appeler exécutable(), le shell ferme la sortie standard et ouvre le fichier nouveau fichier, ainsi, toutes les sorties du programme en cours d'exécution wc sera redirigé vers un fichier au lieu d’un écran.

Tube Unix sont implémentés de la même manière, à la différence qu'ils utilisent un appel pipe(). Dans ce cas, le flux de sortie du processus sera connecté à une file d'attente située dans le noyau, à laquelle le flux d'entrée d'un autre processus sera connecté.

Source: habr.com

Ajouter un commentaire