Je cherchais à trouver la différence entre ces quatre appels sur Google et je m'attendais à ce qu'il y ait une énorme quantité d'informations à ce sujet, mais il n'y avait vraiment aucune comparaison solide entre les quatre appels.
J'ai essayé de compiler une sorte d'aperçu de base des différences entre ces appels système et voici ce que j'ai obtenu. Toutes ces informations sont-elles correctes ou ai-je oublié quelque chose d'important ?
Fork
: L'appel fork crée essentiellement un double du processus actuel, identique en presque tous points (tout n'est pas copié, par exemple, les limites de ressources dans certaines implémentations, mais l'idée est de créer une copie aussi proche que possible).
Le nouveau processus (enfant) obtient un ID de processus (PID) différent et a le PID de l'ancien processus (parent) comme son PID parent (PPID). Comme les deux processus exécutent maintenant exactement le même code, ils peuvent dire lequel est lequel par le code de retour de fork - l'enfant obtient 0, le parent obtient le PID de l'enfant. Tout ceci, bien sûr, en supposant que l'appel fork fonctionne - si ce n'est pas le cas, aucun enfant n'est créé et le parent reçoit un code d'erreur.
Vfork
: La différence fondamentale entre vfork et fork est que lorsqu'un nouveau processus est créé avec vfork(), le processus parent est temporairement suspendu, et le processus enfant pourrait emprunter l'espace d'adressage du parent. Cet étrange état de fait se poursuit jusqu'à ce que le processus enfant quitte, ou appelle execve(), auquel cas le processus parent continue. parent continue.
Cela signifie que le processus enfant d'un vfork() doit faire attention à ne pas modifier de manière inattendue les variables du processus parent. En particulier, le processus enfant ne doit pas retourner de la fonction contenant l'appel vfork(), et il ne doit pas appeler exit() (s'il doit sortir, il devrait utiliser _exit() ; en fait, c'est aussi vrai pour l'enfant d'un fork() normal).
Exec :
L'appel exec est un moyen de remplacer l'ensemble du processus actuel par un nouveau programme. Il charge le programme dans l'espace du processus actuel et l'exécute à partir du point d'entrée. exec() remplace le processus actuel par un exécutable pointé par la fonction. Le contrôle ne revient jamais au programme d'origine, sauf en cas d'erreur de exec().
Clone :
Clone, comme fork, crée un nouveau processus. Contrairement à fork, ces appels permettent au processus enfant de partager des parties de son contexte d'exécution avec le processus appelant, comme l'espace mémoire, la table des descripteurs de fichiers et la table des gestionnaires de signaux.
Lorsque le processus enfant est créé avec clone, il exécute la fonction application fn(arg). (Cela diffère de for, où l'exécution se poursuit dans le processus fils à partir du point d'appel de fork). L'argument fn est un pointeur vers une fonction qui est appelée par le processus enfant au début de son exécution. L'argument arg est passé à la fonction fn.
Lorsque l'application de la fonction fn(arg) revient, le processus enfant se termine. Le nombre entier renvoyé par fn est le code de sortie du processus fils. Le processus enfant peut aussi se terminer explicitement en appelant exit(2) ou après avoir reçu un signal fatal.
Formulaire d'obtention d'informations :
- http://stackoverflow.com/questions/1653340/exec-and-fork
- http://www.allinterview.com/showanswers/59616.html
- http://www.unixguide.net/unix/programming/1.1.2.shtml
- http://linux.about.com/library/cmd/blcmdl2\_clone.htm
Merci d'avoir pris le temps de lire ceci ! :)
2 votes
Pourquoi vfork ne doit-il pas appeler exit() ? Ou ne pas retourner ? Est-ce que exit() n'utilise pas simplement _exit() ? J'essaie également de comprendre :)
2 votes
@Gnuey : parce qu'il est potentiellement (s'il est mis en oeuvre différemment de
fork()
ce qu'il est dans Linux, et probablement dans tous les BSDs) empruntant l'espace d'adressage de son parent. Tout ce qu'il fait, à part appelerexecve()
o_exit()
a un grand potentiel pour perturber le parent. En particulier,exit()
appelleatexit()
et d'autres "finaliseurs", par exemple : il vide les flux stdio. Le retour d'unvfork()
enfant pourrait potentiellement (même mise en garde que précédemment) perturber la pile du parent.0 votes
Je me demande ce qu'il advient des threads du processus parent. Sont-ils tous clonés ou seulement le thread qui appelle la fonction
fork
syscall ?0 votes
@LazerSharks vfork produit un processus de type thread où la mémoire est partagée sans protection contre la copie en écriture, donc faire des trucs de pile pourrait détruire le processus parent.