Quand appeler fork () et exec () par eux-mêmes?

9

J'apprends les commandes fork () et exec (). Il semble que fork () et exec () soient généralement appelés ensemble. (fork () crée un nouveau processus enfant et exec () remplace l'image de processus actuelle par une nouvelle.) Cependant, dans quels scénarios pourriez-vous appeler chaque fonction seule? Existe-t-il des scénarios comme ceux-ci?

quil
la source
2
Forkbomb traditionnel: while (1) fork (); pour monopoliser les ressources du système.
Joshua

Réponses:

22

Sûr! Un modèle courant dans les programmes "wrapper" est de faire diverses choses et de se remplacer ensuite par un autre programme avec seulement un execappel (pas de fork)

#!/bin/sh
export BLAH_API_KEY=blub
...
exec /the/thus/wrapped/program "$@"

Un exemple réel de ceci est GIT_SSH(bien git(1)qu'il offre également GIT_SSH_COMMANDsi vous ne voulez pas faire la méthode de programme wrapper ci-dessus).

Fork-only est utilisé lors de la génération d'un tas de processus typiquement ouvriers (par exemple Apache httpden mode fork (bien que fork-only convienne mieux aux processus qui ont besoin de brûler le CPU et non à ceux qui tournent les pouces en attendant que les E / S réseau se produisent) ) ou pour la séparation de privilèges utilisée par sshdet d'autres programmes sur OpenBSD (pas d'exéc)

$ doas pkg_add pstree
...
$ pstree | grep sshd
 |-+= 70995 root /usr/sbin/sshd
 | \-+= 28571 root sshd: jhqdoe [priv] (sshd)
 |   \-+- 14625 jhqdoe sshd: jhqdoe@ttyp6 (sshd)

Le rootsshd a sur la connexion cliente dérivé une copie de lui-même (28571) puis une autre copie (14625) pour la séparation des privilèges.

branler
la source
14

Il y a plein.

Les programmes qui appellent fork()sans exec()suivent généralement un schéma de processus de génération d'enfants travailleurs pour effectuer diverses tâches dans des processus distincts du processus principal. Vous trouverez dans des programmes aussi variés que dhclient, php-fpmet urxvtd.

Un programme qui appelle exec()sans fork()est le chargement en chaîne , superposant son processus avec une image de programme différente. Il existe toute une sous-culture d'utilitaires de chargement de chaîne qui font des choses particulières pour traiter l'état, puis exécutent un autre programme pour s'exécuter avec cet état de processus révisé. De tels utilitaires sont courants dans la famille de jeux d'outils de gestion de systèmes et de services daemontools, mais ne sont pas limités à ceux-ci. Quelques exemples:

Les boîtes à outils de la famille daemontools ont beaucoup de ces outils, de machineenvpar find-matching-jvmà runtool.

JdeBP
la source
2

En plus d'autres réponses, les débogueurs utilisant utilisent ptracegénéralement l'écart entre forket exec. Un débogueur doit se marquer avec PTRACE_TRACEMEpour indiquer qu'il est tracé par son processus parent - le débogueur. Il s'agit de donner les autorisations requises au débogueur.

Ainsi, un débogueur se bifurquerait d'abord. L'enfant appelait ptraceavec PTRACE_TRACEMEpuis appelait exec. Quel que soit le programme, les enfants exécutables seront désormais traçables par le parent.

bytefire
la source
Il existe de nombreux exemples de choses entre fork et exec, la plus courante étant la redirection d'E / S (par exemple, la configuration de canaux). Mais la question est de faire du fork sans aucun exécutable.
Barmar
0

exec sans fourche

Il y a au moins deux raisons pour lesquelles vous voudriez faire une telle chose:

  1. Chargement de la chaîne. L'image de processus actuelle est remplacée par quelque chose de différent.
  2. Redémarrage du programme en cours d'exécution (peut par exemple se produire lorsque vous SIGHUP ou un tel processus serveur, tout recharger et faire un nouveau départ). D'une certaine manière, on pourrait soutenir qu'il s'agit d'un chargement de chaîne, uniquement par coïncidence avec le même programme.

fourche sans exec

C'est ce que fait chaque démon à chaque démarrage (deux fois, en effet). Cela fait plusieurs choses, parmi lesquelles le shell ne se bloque pas (puisque le processus d'origine sur lequel le shell attend se termine) et le démon n'est plus contrôlé par le terminal, donc la fermeture de la fenêtre du shell ne tue pas le démon.

Une autre utilisation courante est le fait de bifurquer les enfants travailleurs, qui a été rendu célèbre par le serveur Web Apache il y a environ 25 ans (de nos jours, cela n'est plus considéré comme étant à la pointe de la technologie en raison de sa prédisposition au problème du troupeau tonitruant, mais il fournit certainement la serveur le plus simple et le plus robuste possible).

Pourtant, une autre utilisation courante consiste à créer un instantané cohérent. forkcrée non seulement un processus, mais copie également (en théorie, il ne marque que les pages copiées sur écriture) l'espace d'adressage. Cela (atomiquement) crée un instantané des données complètes du programme que le parent ne peut plus modifier.
Certains programmes en profitent. Par exemple, redis enregistre les données sur le disque (dans un état cohérent) tout en modifiant simultanément l'ensemble de données. Cela ne fonctionne que parce forkque vous avez créé un instantané cohérent qui ne voit pas les modifications apportées par le processus parent.

Damon
la source
Il y a en fait très peu de démons de nos jours, la plupart ne le font pas en standard ou n'ont pas de mode couramment utilisé. Il est une erreur de la fourche menant à décalage de préparation et d' horreurs , et est l' une des erreurs de l'erreur de démonisation . Cette erreur est enfin largement tombée en disgrâce.
JdeBP