37 votes

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

Quelle est la différence entre fork() y vfork() ? Est-ce que vfork() retourner comme fork() .

39voto

Blagovest Buyukliev Points 22767

L'intention de vfork était d'éliminer la surcharge de la copie de l'image du processus entier si vous voulez seulement faire une exec* dans l'enfant. Parce que exec* remplace l'ensemble de l'image du processus enfant, il est inutile de 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'utilisation, vfork est dangereux et imprévisible.

Cependant, avec la plupart des noyaux actuels, y compris Linux, le principal avantage de l'option vfork a disparu à cause 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.

27voto

dcoz Points 181

Comme il a déjà été dit, le vfork est claire sur les différences. Ce site sujet donne une bonne description de fork , vfork , clone y exec .

Voici quelques différences souvent négligées entre fork y vfork J'en ai fait l'expérience sur certains systèmes embarqués Linux 2.6.3x avec lesquels j'ai travaillé.

Même avec les techniques de copie sur écriture, 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 la mémoire qui est utilisée et pas seulement allouée), fork échoue si vous avez moins de 2 Go de mémoire libre. C'est frustrant lorsque vous voulez juste exec un programme simple et n'aura donc jamais besoin de cet énorme espace d'adressage parent !

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

Parce que les tables de pages de mémoire ne sont pas dupliquées, vfork est beaucoup plus rapide que fork y vfork Le temps d'exécution d'un processus n'est pas affecté par la quantité de mémoire utilisée par le processus parent, comme indiqué 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 la mémoire limitée, vfork + exec* peut donc être une bonne alternative à fork + exec* . Le problème est qu'il est moins sûr et que la page de manuel indique que vfork est susceptible d'être déprécié à l'avenir.

Une solution plus sûre et plus portable peut consister à examiner la posix_spawn qui est de niveau supérieur et offre plus d'options. Elle utilise en toute sécurité vfork lorsque cela est possible, en fonction des options que vous lui passez. J'ai été capable d'utiliser posix_spawn avec succès et surmonter cet ennuyeux "problème de double vérification de la mémoire" qui fork + exec me donnait.

Une très bonne page sur ce sujet, avec des liens vers d'autres sites. posix_spawn exemples.

4voto

SiegeX Points 32614

De ma page de manuel

(Extrait de POSIX.1) La fonction vfork() a le même effet que fork(2), sauf que t processus créé par vfork() modifie toute donnée autre qu'une variable de type pid_t utilisée pour enregistrer la valeur de retour de vfork(), ou retourne de l'application fonction dans laquelle vfork() a été appelée, ou appelle toute autre fonction avant d'avoir réussi à appeler _exit(2) ou fonctions.

vfork() diffère de fork(2) par les points suivants que le parent est suspendu jusqu'à ce que le enfant se termine (soit normalement, en appelant _exit(2), ou anormalement, après la délivrance d'un signal fatal), ou qu'il fasse un appel à execve(2). Jusqu'à ce moment, l'enfant enfant partage toute la mémoire avec son parent, y compris la pile. L'enfant ne doit pas retourner de la fonction courante ou appeler exit(3), mais peut appeler _exit(2).

2voto

cpp-coder Points 47

Certains systèmes ont un appel système vfork(), qui a été conçu à l'origine comme une version moins coûteuse de fork(). Puisque fork() impliquait de copier l'espace d'adressage entier du processus, et était donc assez coûteuse, la fonction vfork() a été introduite (dans 3.0BSD).

Cependant, depuis l'introduction de vfork(), l'implémentation de fork() s'est améliorée de façon drastique, plus particulièrement avec l'introduction de `copy-on-write', où la copie de l'espace d'adressage du processus est simulée 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'entre eux la modifie. Cela supprime en grande partie la justification de vfork() ; en effet, une grande proportion de systèmes n'ont plus du tout la fonctionnalité originale de vfork(). vfork() complètement. Pour des raisons de compatibilité, cependant, il peut toujours y avoir un appel vfork() présent, qui appelle simplement fork() sans essayer d'émuler toute la sémantique de vfork().

Par conséquent, il est très peu judicieux d'utiliser les différences entre fork() et vfork(). En effet, il est probablement peu judicieux d'utiliser vfork() du tout, sauf si vous savez exactement pourquoi vous le voulez.

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'adressage du parent. Cet état étrange des choses continue jusqu'à ce que le processus enfant sorte, ou appelle execve(), à quel point le processus 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 a besoin de sortir, il devrait utiliser _exit() ; en fait, c'est aussi vrai pour l'enfant d'un fork() normal).

1voto

Vishal Points 4060

Consultez le site aquí et de wikipedia -

Sur certains systèmes, vfork( que fork(). La fonction vfork() ne diffère de fork() que par le fait que la fonction processus enfant peut partager du code et des données avec le processus appelant (processus parent). parent).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X