Comment fonctionnent fork et exec?

17

Je n'ai pas beaucoup d'expérience, j'essaye simplement de m'impliquer dans les processus comment interprètent-ils le matériel au niveau de l'utilisateur.

Ainsi, lorsqu'une commande est lancée à partir d'un shell, fork()hérite d'un processus enfant de celui-ci et exec()charge le processus enfant dans la mémoire et s'exécute.

  1. Si le processus enfant contient tous les attributs du processus parent (qui est le processus d'origine), alors quel est le besoin de ce processus enfant? Le processus d'origine aurait également pu être chargé dans la mémoire.
  2. Est-ce que ceci forket le execconcept s'appliquent à tous les programmes exécutables sous UNIX? Comme pour le script shell également ou uniquement pour les commandes? Cela s'applique-t-il également aux commandes intégrées du shell?
  3. Quand le concept de copie sur écriture est-il utilisé si j'exécute une commande / un script?

Désolé de poser beaucoup de questions à la fois, mais toutes ces questions me viennent à l'esprit en même temps quand je pense à une exécution de commande.

PriB
la source
Je ne dirai pas qu'il s'agit d'un doublon, mais je pense que certaines de vos questions trouvent une réponse ici: unix.stackexchange.com/questions/136637/… et dans l'autre réponse liée en haut de celle-ci.
goldilocks

Réponses:

22

Ainsi, lorsqu'une commande est lancée à partir d'un shell, fork () en hérite un processus enfant et exec () charge le processus enfant dans la mémoire et s'exécute.

Pas assez. fork()clone le processus en cours, créant un enfant identique. exec()charge un nouveau programme dans le processus actuel, en remplaçant le programme existant.

Mon qs est:

Si le processus enfant contient tous les attributs du processus parent (qui est le processus d'origine), alors quel est le besoin de ce processus enfant? Le processus d'origine aurait également pu être chargé dans la mémoire.

Le besoin est dû au fait que le processus parent ne veut pas encore se terminer; il veut qu'un nouveau processus se déclenche et fasse quelque chose en même temps qu'il continue de s'exécuter également.

Ce concept fork et exec s'applique-t-il à tous les programmes exécutables sous UNIX? Comme pour le script shell également ou uniquement pour les commandes? Cela s'applique-t-il également aux commandes intégrées du shell?

Pour les commandes externes, le shell fait un fork()pour que la commande s'exécute dans un nouveau processus. Les commandes internes sont simplement exécutées directement par le shell. Une autre commande notable est exec, qui indique le shell au exec()programme externe sans d'abordfork() . Cela signifie que le shell lui-même est remplacé par le nouveau programme et qu'il n'est donc plus là pour que ce programme revienne à sa sortie. Si vous dites ``, exec truealors /bin/trueremplacera votre shell et quittera immédiatement, ne laissant plus rien fonctionner dans votre terminal, donc il se fermera.

lorsque le concept de copie sur écriture est utilisé si j'exécute une commande / un script?

À l'époque de l'âge de pierre, il fork()fallait en fait copier toute la mémoire du processus d'appel vers le nouveau processus. Copier lors de l'écriture est une optimisation dans laquelle les tables de pages sont configurées de sorte que les deux processus commencent par partager la même mémoire, et seules les pages écrites par l'un ou l'autre processus sont copiées en cas de besoin.

psusi
la source
4
"Pour presque toutes les commandes, le shell fait un fork () afin que la commande s'exécute dans un nouveau processus. Si cette commande est une commande intégrée, alors l'enfant n'a pas besoin d'exécuter () un programme distinct." Bonne réponse, mais cette partie devrait être modifiée. Le shell ne bifurque pas lors de l'exécution de buildins Il les exécute directement dans le processus shell actif. C'est la seule façon dont les buildins aiment cdou readpourraient fonctionner. Le manque de bifurcation rend également les commandes intégrées beaucoup plus rapides que les commandes externes.
John Kugelman soutient Monica du
6
  1. Pour certains programmes, le processus enfant fait une chose (lire à partir d'un port série, écrire sur le terminal), et le processus parent continue à faire autre chose (lire à partir du terminal, écrire sur le port série). Un autre exemple classique est que le processus enfant effectue un point de contrôle de tout calcul à long terme en cours. Généralement, le processus enfant effectue une configuration, comme changer de répertoire, réinitialiser les gestionnaires de signaux ou réinitialiser les descripteurs de fichiers, puis appelle execve()pour se superposer avec un code différent.
  2. fork()et exec()s'appliquent à tous les exécutables - en fait, avec argc et argv, et les tuyaux, fork et exec sont ce qui distingue Unix des autres systèmes d'exploitation. Quelques spécialisations ou généralisations fork()existent, comme BSD vfork(), Plan 9 rfork()et Linux ' clone(), mais le principe reste le même.
  3. "copier sur écriture" n'apparaît pas vraiment à l'utilisateur, c'est plutôt une technique pour optimiser la création d'un processus enfant, et pendant son exécution. La pile d'appels et le tas (mémoire allouée avec malloc(), ou même des variables d'étendue statiques ou globales) peuvent être "copiés en écriture". Lorsqu'un processus enfant est créé avec unfork(), le noyau configurerait le processus enfant pour avoir exactement les mêmes pages de mémoire que le tas et la pile comme le processus parent. Si le matériel (unité de gestion de la mémoire) détecte une écriture du tas ou de la pile, le noyau obtient une nouvelle page physique de mémoire, copie la page du parent dans la nouvelle page et mappe cette nouvelle page dans la pile ou le tas du processus enfant. Cela constitue une optimisation car le noyau passe moins de temps à configurer les mappages de pages qu'il ne le ferait pour copier la pile et le tas complètement pour le processus enfant.
Bruce Ediger
la source
Merci Bruce pour ta réponse. Mais tant de choses que vous avez dites ici me dépassent la tête. Je n'ai pas beaucoup de connaissances avec ces choses .. J'essaierai de faire fonctionner ces fonctions que vous avez mentionnées. Merci beaucoup..!!
PriB
4
Si le processus enfant contient tous les attributs du processus parent (qui est le processus d'origine), alors quel est le besoin de ce processus enfant? Le processus d'origine aurait également pu être chargé dans la mémoire.

Cette question trouve une réponse très illustrative en jetant un coup d'œil aux premières implémentations Unix qui devaient fonctionner sous des contraintes de mémoire sévères et n'avaient qu'un seul processus d'exécution dans l'espace mémoire / adresse à la fois.

Le multitâche a été réalisé en échangeant un processus vers le disque et en échangeant un processus différent vers.

Maintenant, l' forkappel système était presque le même: il a échangé un processus sur le disque, mais au lieu d'échanger un autre processus, il a donné à la copie en mémoire un autre ID de processus et y est revenu. Et c'était un moment opportun pour que ce processus décide de se lancer execdans un autre exécutable après tout.

fork+ execn'entraînait donc pas de surcharge notable lors du frai: vous deviez quand même échanger votre processus sur le disque et vous aviez quand même l'ancienne image de processus dans des emplacements de mémoire exploitables.

Avec des quantités croissantes de mémoire et d'unités de gestion de mémoire disponibles et de multiples processus en mémoire, le coût initialement négligeable d'une fourchette est devenu un peu plus gênant pour certaines architectures: ainsi vforkest né.

user99727
la source
2

Pour rendre cela aussi facile à comprendre que possible, j'utiliserai une analogie. Préparons une tarte!

Nous prenons le livre de recettes, commençons à lire et nous installons sur une tarte à la rhubarbe aux fraises (ma préférée), avec une croûte à la main. Presque tout ce dont nous avons besoin est dans la cuisine, sauf les œufs et les fruits, mais comme nous vivons dans une ferme et que les fruits sont de saison, ce n'est pas un problème. le problème est que le four est cassé et qu'il n'y a pas assez de temps pour tout faire. Ce ne serait pas bien d'avoir plus d'un de moi?

fork () à la rescousse. Maintenant, je suis deux. et nous nous dirigeons tous les deux vers la cuisine pour commencer à faire la croûte de tarte. Oups. Nous regardons donc le retour de fork. J'ai obtenu un grand nombre, il a obtenu zéro, alors je me dirige vers la cuisine pendant qu'il se dirige vers le poulailler et le jardin. Alors que je passe devant le four, je bifurque () à nouveau, regardez la valeur de retour: bummer I got zero. Il continue sur la farine pendant que je regarde le four cassé. J'ouvre la porte, pas de lumière, je ferme la porte. Est-ce que quelqu'un sait réparer un four?

exec () à la rescousse. J'atteins le voltmètre sur ma ceinture porte-outils, l'ampoule pourrait être diagnostique, donc je vérifie la puissance, En effet disjoncteur déclenché, solution facile. en marchant vers le panneau de bris, je vois un camarade cueillir de la rhubarbe. Beurk! Je préfère la tarte au chocolat et à la soie.

hildred
la source