Quelle est la différence entre fork() et vfork()?

Quelle est la différence entre fork() et vfork() ? Ne vfork() retourner comme fork() .

29
demandé sur Jonathan Leffler 2010-11-23 21:51:28

6 réponses

le but de vfork était d'éliminer le coût de copie de l'image complète du procédé si vous voulez seulement faire un exec* dans l'enfant. Parce que exec* remplace l'image entière du processus enfant, il n'y a aucun intérêt à copier l'image du parent.

if ((pid = vfork()) == 0) {
  execl(..., NULL); /* after a successful execl the parent should be resumed */
  _exit(127); /* terminate the child in case execl fails */
}

Pour d'autres types d'utilisations, vfork est dangereux et imprévisible.

avec la plupart des noyaux actuels, cependant, y compris Linux, le principal avantage de vfork a disparu en raison de la façon dont fork est mis en œuvre. Plutôt que de copier l'image entière lorsque fork est exécuté, des techniques de copie-sur-écriture sont utilisées.

34
répondu Blagovest Buyukliev 2015-02-10 06:30:45

comme déjà indiqué, la page de manuel vfork est claire sur les différences. Ce thème donne une bonne description de fork , vfork , clone et exec .

ci-dessous sont quelques différences souvent négligées entre fork et vfork j'ai expérimenté sur certains Linux 2.6.3 x systèmes embarqués, j'ai travaillé avec.

même avec la copie-sur-Écrire des techniques, fork échoue si vous n'avez pas assez de mémoire pour dupliquer la mémoire utilisée par le processus parent. Par exemple, si le processus parent utilise 2 Go de mémoire résidente (c'est-à-dire de mémoire qui est utilisée et pas seulement attribuée), fork échoue si vous avez moins de 2 Go de mémoire libre. C'est frustrant quand vous voulez juste exec un programme simple et donc n'aura jamais besoin de cet espace d'adresse parent énorme!

vfork n'a pas ce problème de mémoire, car il ne duplique pas le espace d'adresse des parents. Le processus enfant agit plus comme un fil dans lequel vous pouvez appeler exec* ou _exit sans nuire à votre processus parent.

parce que les tables de page de mémoire ne sont pas dupliquées, vfork est beaucoup plus rapide que fork et vfork le temps d'exécution de" n'est pas affecté par la quantité de mémoire que le processus parent utilise, comme souligné ici: http://blog.famzah.net/2009/11/20/fork-gets-slower-as-parent-process-use-more-memory/

dans les situations où les performances sont critiques et/ou limitées en mémoire, vfork + exec* peut donc être une bonne alternative à fork + exec* . Le problème est qu'il est moins sûr et la page de man dit vfork est susceptible de devenir obsolète dans l'avenir.

une solution plus sûre et plus portable peut être de regarder la fonction posix_spawn , qui est de niveau supérieur et offre plus d'options. Il utilise en toute sécurité vfork lorsque possible, en fonction des options que vous lui passez. J'ai été en mesure d'utiliser posix_spawn avec succès et surmonter ce problème ennuyeux "double vérification de mémoire" que fork + exec me donnait.

une très bonne page sur ce sujet, avec des liens vers des exemples posix_spawn .

21
répondu dcoz 2017-05-23 12:17:50

De ma page de manuel de

(de POSIX.1) la fonction vfork () a le même effet que la fourchette(2), sauf que le comportement est indéfini si l' processus créé par vfork () modifie une donnée autre qu'une variable de type pid_t utilisé pour stocker la valeur de retour de vfork(), ou des retours de la fonction dans laquelle vfork() a été appelé, ou appelle toute autre fonction avant d'appeler avec succès _exit(2) ou l'un des exec(3) de la famille des fonction.

vfork () diffère de fork (2) en que le parent est suspendu jusqu'à ce que le enfant prend fin (normalement, par appeler _exit(2), ou anormalement, après la livraison d'un signal fatal), ou il fait un appel à execve (2). Jusqu'à ce point, la l'enfant partage toute sa mémoire avec sa société mère, y compris la pile. L'enfant ne doit pas retourner de la fonction courante ou la sortie d'appel(3), mais peut appeler _exit(2).

4
répondu SiegeX 2010-11-23 18:52:23

certains systèmes ont un système appelé vfork (), qui a été initialement conçu comme une version de fork (). Puisque fork () impliquait de copier la totalité de l'espace d'adresse du processus, et était donc assez cher, la fonction vfork() a été introduite (en 3.0 BSD).

cependant, depuis l'introduction de vfork (), la mise en œuvre de fork() s'est considérablement améliorée, notamment avec l'introduction de `copy-on-write', où la copie de l'adresse du processus l'espace est simulé de façon transparente en permettant aux deux processus de se référer à la même mémoire physique jusqu'à ce que l'un d'eux la modifie. Cela supprime en grande partie la justification de vfork(); en effet, une grande partie des systèmes ne disposent plus de la fonctionnalité d'origine de vfork. vfork() complètement. Pour la compatibilité, cependant, il peut encore y avoir un appel vfork() présent, qui appelle simplement fork() sans tenter d'émuler toute la sémantique de vfork ().

en conséquence, il est très imprudent de utilisez en fait l'une des différences entre fork() et vfork(). En effet, il est sans doute imprudent d'utiliser vfork (), sauf si vous savez exactement pourquoi vous le souhaitez.

la différence fondamentale entre les deux est que lorsqu'un nouveau processus est créé avec vfork(), le processus parent est temporairement suspendu, et le processus enfant peut emprunter l'espace d'adresse du parent. Cet étrange état de choses continue jusqu'à ce que le processus de l'enfant soit sort, soit appelle execve (), auquel le processus parent continue.

cela signifie que le processus enfant d'une vfork() doit être prudent pour éviter de modifier de façon inattendue les variables du processus parent. En particulier, le processus enfant ne doit pas revenir de la fonction contenant l'appel vfork (), et il ne doit pas appeler exit() (s'il doit sortir, il doit utiliser _exit(); en fait, ceci est également vrai pour l'enfant d'un fork normal()).

2
répondu cpp-coder 2013-12-26 19:12:04

Consultez ici et de wikipedia -

sur certains systèmes, vfork () est le même as fork (). Le vfork() la fonction diffère de fork () seulement en ce que le processus enfant peut partager code et données avec le processus d'appel (parent processus.)

1
répondu Vishal 2010-11-23 18:54:46

la différence fondamentale entre les deux est que lorsqu'un nouveau processus est créé avec vfork() , le processus parent est temporairement suspendu, et le processus enfant peut emprunter l'espace d'adresse du parent. Cette situation étrange se poursuit jusqu'à ce que le processus de l'enfant cesse, ou appelle execve() , et que le processus parental se poursuive.

cela signifie que le processus enfant d'un vfork() doit être prudent de évitez de modifier de façon inattendue les variables du processus parent. Dans en particulier, le processus de l'enfant ne doit pas revenir de la fonction contenant l'appel vfork() , et il ne doit pas appeler exit() (si elle doit sortir, elle doit utiliser _exit(); en fait, cela est également vrai pour l'enfant à la normale fork() ).

cependant, depuis que vfork() a été introduit, le la mise en œuvre de fork() s'est considérablement améliorée, notamment avec l'introduction de "copie à l'écriture", de où la copie de la processus l'espace d'adresse est truqué de manière transparente en permettant les deux processus pour faire référence à la même mémoire physique jusqu'à ce que l'un d'eux modifie il. cela supprime largement la justification de vfork(); en effet, un une grande partie des systèmes ne disposent plus de la fonctionnalité d'origine vfork() complètement. Pour la compatibilité, cependant, il peut encore y avoir un vfork() appel présent, qui appelle simplement fork() sans tenter pour imiter toute la sémantique vfork() .

en conséquence, il est très imprudent de faire usage de l'un des différences entre fork() et vfork() . En effet, il est probablement pas sage d'utiliser vfork() du tout, sauf si vous savez exactement pourquoi vous le souhaitez.

1
répondu Rajesh Pal 2015-03-27 21:00:14