5
votes

Créer un processus enfant SANS fork ()

Existe-t-il un moyen de démarrer un processus enfant sans fork () , en utilisant exclusivement execvp () ?


10 commentaires

Oui, si le processus créé par execvp utilise fork ou clone ... Cette question n'a aucun sens sans justification fournie.


execvp remplace votre processus par un autre exécutable donc à peine un processus enfant . Pourquoi la résistance au fork ?


Malheureusement, il n'y a pas de rationnel derrière la question car il y a cette restriction spécifique sur mon projet.


Si vous avez une restriction sur l'utilisation de fork , vous n'êtes pas censé créer un processus enfant, c'est tout. Ou peut-être veulent-ils que vous utilisiez clone .


La création d'un processus enfant est une demande non négociable selon les instructions données par le professeur. execvp uniquement!


Pourriez-vous nous citer la déclaration complète des restrictions sur votre projet? Il est possible que vous soyez censé apprendre quelque chose de subtil sur Unix en découvrant que vous ne pouvez démarrer un processus enfant sans fork , mais il est également possible que vous ayez mal compris la tâche.


Alors soit vous avez mal compris le devoir, soit le professeur demande l'impossible.


execvp ne crée pas de nouveau processus, il exécute un nouveau programme dans le contexte de votre processus actuel.


Quel est le système d'exploitation? Il existe de nombreux systèmes d'exploitation qui n'utilisent pas du tout fork ().


man vfork (); ou si vous vouliez être encore plus malhonnête, system ().


4 Réponses :


2
votes

Contrairement aux systèmes Windows, où la création d'un nouveau processus et l'exécution d'une nouvelle image de processus se produisent en une seule étape, Linux et d'autres systèmes de type UNIX les exécutent en deux étapes distinctes.

La fonction fork fait une copie exacte du processus appelant et retourne en fait deux fois, une fois au processus parent et une fois au processus enfant. La fonction execvp (et d'autres fonctions de la famille exec ) exécute une nouvelle mémoire image dans le même processus, écrasant la mémoire image existante.

Vous pouvez appeler execvp sans appeler fork au préalable. Si tel est le cas, cela signifie simplement que le programme en cours d'exécution disparaît et est remplacé par le programme donné. Cependant, fork est le moyen de créer un nouveau processus.


1 commentaires

écrasant l'image de processus existante en entrant dans les détails de l'implémentation J'imagine que c'est fait paresseux et que seules les tables de pages sont remplacées dans un premier temps par les registres.



6
votes

La réponse pédante à votre question est non. Le seul appel système qui crée un nouveau processus est fork . L'appel système sous-jacent execvp (appelé execve ) charge un nouveau programme dans un processus existant, ce qui est différent.

Certaines espèces d'Unix ont des appels système supplémentaires en plus de fork (par exemple vfork , rfork , clone ) qui créer un nouveau processus, mais ce ne sont que de petites variations de fork lui-même, et aucune d’entre elles ne fait partie du standard POSIX qui spécifie la fonctionnalité sur laquelle vous pouvez compter sur tout s'appelle un Unix.

La réponse un peu plus utile est que vous recherchez peut-être posix_spawn , qui est une routine de bibliothèque regroupant fork et exec en un seul opération, mais je trouve plus gênant de l’utiliser correctement que d’écrire mon propre sous-programme fork + exec . YMMV.


5 commentaires

@DanO Je ne pense pas que cela fasse suffisamment de différence pour changer ma réponse. Bien sûr, posix_spawn pourrait utiliser une nouvelle primitive fork-with-options, quel que soit son nom, plutôt que le fork d'origine (2), mais c'est toujours une routine de bibliothèque qui encapsule une opération fork et une opération exec . Son algorithme n'a pas changé.


@DanO s'il vous plaît relisez le deuxième paragraphe de la réponse: le clone a été mentionné depuis que je l'ai écrit. Puisque le clone n'est qu'une petite variation de fork, son existence n'invalide pas mon point d'origine, pas plus que vfork.


Désolé, je ne le vois tout simplement pas. Tant que posix_spawn est implémenté en faisant une opération fork et une opération exec, je pense que ce que la réponse dit actuellement est exact. Les noms des appels système impliqués ne sont pas importants.


Vous insistez sur une distinction qui, pour autant que je sache, ne correspond pas à une différence réelle. Le clone effectue une opération de fork.


J'écrirai ma propre réponse.



0
votes

Comme l'utilisateur zwol l'a déjà expliqué, execve () ne lance pas un nouveau processus. Au contraire, il remplace l'espace d'adressage et l'état du processeur du processus courant , charge le nouvel espace d'adressage à partir du nom de fichier exécutable et le démarre à partir de main () avec liste d'arguments argv et liste de variables d'environnement envp . Il garde les fichiers pid et ouverts.

int execve(const char *filename,char *const argv [],char *const envp[]);

filename : nom du fichier exécutable à exécuter
argv : arguments de ligne de commande
envp : paramètres de la variable d'environnement (par exemple, $ PATH , $ HOME , etc.)


0 commentaires

0
votes

posix_spawn est le seul moyen compatible avec posix de créer un processus enfant sans appeler fork directement. Je dis «directement» parce qu'historiquement posix_spawn s'appellerait simplement fork ou vfork . Cependant, ce n'est plus le cas dans GNU / linux. posix_spawn lui-même peut être plus efficace que fork , en plus d'être peut-être un ajustement conceptuel plus fort lorsque le code tente d'exécuter un exécutable différent.

Si vous n'êtes pas préoccupé par la portabilité, vous pouvez abandonner posix et vous coupler directement au noyau que vous ciblez. Sous Linux, l'appel système pour créer un processus enfant est clone . Au moment de cette réponse, la page de manuel fournit de la documentation pour trois variantes, y compris le relativement nouveau clone3 .

Je pense que vous pouvez prendre l'exemple de la page de manuel et ajouter un appel execvp à childFunc . Mais je ne l'ai pas encore essayé!


0 commentaires