À partir de la page de manuel de vfork()
:
vfork () diffère de fork () en ce que le parent est suspendu jusqu'à ce que l'enfant fasse un appel à execve (2) ou _exit (2). L'enfant partage toute la mémoire avec son parent, y compris la pile, jusqu'à ce que execve () soit émis par l'enfant. L'enfant ne doit pas revenir de la fonction actuelle ou appeler exit (), mais peut appeler _exit ().
Pourquoi l'enfant devrait-il utiliser _exit()
plutôt qu'un simple appel exit()
? J'espère que cela s'applique aux deux vfork()
et fork()
.
c
system-calls
fork
exit
Sen
la source
la source
Réponses:
Comme vu précédemment ,
vfork
ne permet pas au processus enfant d'accéder à la mémoire du parent.exit
est une fonction de bibliothèque C (c'est pourquoi elle est souvent écrite commeexit(3)
). Il effectue diverses tâches de nettoyage telles que le vidage et la fermeture des flux C (les fichiers s'ouvrent via les fonctions déclarées dansstdio.h
) et l'exécution des fonctions spécifiées par l'utilisateur enregistrées avecatexit
. Toutes ces tâches impliquent la lecture et l'écriture dans la mémoire de processus._exit
sort sans nettoyage. Il s'agit directement d'un appel système (c'est pourquoi il est écrit sous la forme_exit(2)
), généralement implémenté en plaçant le numéro d'appel système dans un registre de processeur et en exécutant une instruction de processeur particulière (branchement au gestionnaire d'appels système). Cela n'a pas besoin d'accéder à la mémoire du processus, il est donc sûr de le faire aprèsvfork
.Après
fork
, il n'y a plus de restriction: les processus parent et enfant sont désormais complètement autonomes.la source
init
est forké par le noyau).exit
faire un nettoyage supplémentaire comme appeler des fonctions enregistrées paratexit
donc accéder aux données en dehors de la partie copiée._exit
effectue syscall directement sans aucun nettoyage, sauf dans le noyau.la source
Vous avez l'appel enfant _exit () pour éviter de vider les tampons stdio (ou autres) lorsque le processus enfant se termine. Puisque le processus enfant constitue une copie exacte du processus parent, le processus enfant a toujours tout ce que le parent avait dans "stdout" ou "stderr", les tampons de <stdio.h>. Vous pouvez (et obtiendrez, à des moments inopportuns) obtenir des sorties doubles en appelant exit (), une à partir des gestionnaires atexit du processus enfant et une à partir du parent, lorsque les tampons du processus parent sont saturés et vidés.
Je me rends compte que la réponse ci-dessus se concentre sur les spécificités de stdio.h, mais cette idée se transmet probablement à d'autres E / S tamponnées, comme l'indique l'une des réponses ci-dessus.
la source
exit()
: - effectue une tâche de nettoyage, comme la fermeture des flux d'E / S et de nombreux autres, puis revient au noyau._exit()
: - vient directement au noyau (n'effectuez aucune tâche de nettoyage).fork()
: le parent et l'enfant ont tous deux une table de fichiers différente, donc la modification effectuée par l'enfant n'affecte pas les paramètres d'environnement du parent, et vice versa.vfork()
: le parent et l'enfant utilisent la même table de fichiers, donc la modification effectuée par l'enfant affecte les paramètres d'environnement du parent. Par exemple, une variablevar=10
, maintenant exécutéevar++
par l'enfant puis exécutée par le parent, vous pouvez également voir l'effet devar++
dans la sortie du parent.Comme je l' ai dit , si vous utilisez
exit()
dansvfork()
puis tous les i / o est déjà fermé. Ainsi, même si le parent s'exécute correctement, vous ne pouvez pas obtenir la sortie appropriée, car toutes les variables sont vidées et tous les flux sont fermés.la source