Quando chiamare fork () ed exec () da soli?


9

Sto imparando i comandi fork () ed exec (). Sembra che fork () e exec () siano generalmente chiamati insieme. (fork () crea un nuovo processo figlio ed exec () sostituisce l'immagine del processo corrente con una nuova.) Tuttavia, in quali scenari potresti chiamare ciascuna funzione da sola? Ci sono scenari come questi?


2
Forkbomb tradizionale: while (1) fork (); per sminuire le risorse di sistema.
Giosuè,

Risposte:


22

Sicuro! Un modello comune nei programmi "wrapper" consiste nel fare varie cose e poi sostituirsi con qualche altro programma con una sola execchiamata (senza fork)

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

Un esempio reale di ciò è GIT_SSH(sebbene git(1)offra anche GIT_SSH_COMMANDse non si desidera eseguire il metodo del programma wrapper sopra).

Fork-only viene utilizzato quando si generano un sacco di processi tipicamente worker (ad es. Apache httpdin modalità fork (anche se solo fork si adatta meglio ai processi che devono bruciare la CPU e non quelli che agitano i pollici in attesa che si verifichi l'I / O di rete) ) o per la separazione dei privilegi utilizzata da sshde altri programmi su OpenBSD (no exec)

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

La rootsshd è il client si connettono biforcuta fuori una copia di se stesso (28571) e poi un'altra copia (14625) per la separazione dei privilegi.


14

Ce ne sono in abbondanza.

I programmi che chiamano fork()senza exec()seguono di solito uno schema di generazione di processi figlio lavoratore per eseguire varie attività in processi separati a quello principale. Troverete questo nei programmi diversi come dhclient, php-fpme urxvtd.

Un programma che chiama exec()senza fork()è il caricamento a catena , sovrapponendo il suo processo con un'immagine di programma diversa. Esiste un'intera sottocultura di utilità per il caricamento a catena che fanno particolari cose per elaborare lo stato e quindi eseguire un altro programma da eseguire con quello stato del processo rivisto. Tali utilità sono comuni nella famiglia di servizi di daemontools e nei set di strumenti di gestione del sistema, ma non si limitano a quelli. Alcuni esempi:

I set di strumenti della famiglia dei daemontools hanno molti di questi strumenti, da machineenvfino find-matching-jvma runtool.


2

Oltre ad altre risposte, i debugger ptrace, in genere, sfruttano il divario tra forke exec. Un debuggee dovrebbe contrassegnare se stesso PTRACE_TRACEMEper indicare che è stato rintracciato dal suo processo genitore - il debugger. Questo per dare le autorizzazioni necessarie al debugger.

Quindi un debugger dovrebbe prima biforcarsi. Il bambino chiamerebbe ptracecon PTRACE_TRACEMEe poi chiamerebbe exec. Qualunque programma i dirigenti del bambino saranno ora rintracciabili dal genitore.


Esistono molti esempi di operazioni tra fork e exec, il più comune è il reindirizzamento degli I / O (ad es. Installazione di pipe). Ma la domanda è di fare fork senza alcun dirigente.
Barmar,

0

exec senza forcella

Ci sono almeno due ragioni per cui vorresti fare una cosa del genere:

  1. Caricamento a catena. L'immagine di processo corrente viene sostituita con qualcosa di diverso.
  2. Riavvio del programma attualmente in esecuzione (ad esempio potrebbe verificarsi quando si avvia SIGHUP o un tale processo del server, ricaricando tutto e facendo un nuovo avvio). In qualche modo, si potrebbe sostenere che si tratti di un caricamento a catena, solo in coincidenza con lo stesso programma.

forcella senza esec

Questo è ciò che ogni demone fa ogni volta che viene avviato (due volte, in effetti). Questo fa diverse cose, tra cui la shell non si blocca (poiché il processo originale su cui la shell attende termina) e il demone non è più controllato dal terminale, quindi chiudere la finestra della shell non uccide il demone.

Un altro uso comune è il fork dei figli dei lavoratori, che è stato reso famoso dal web server apache circa 25 anni fa (al giorno d'oggi questo non è più considerato all'avanguardia a causa della fragilità del gregge, ma fornisce sicuramente il dannatamente il server più semplice e robusto possibile).

Un altro uso comune è creare un'istantanea coerente. forknon solo crea un processo, ma copia anche (in teoria, in realtà segna solo pagine copy-on-write) lo spazio degli indirizzi. Questo (atomicamente) crea un'istantanea dei dati completi del programma che il genitore non può più modificare.
Alcuni programmi ne approfittano. Ad esempio redis salva i dati su disco (in uno stato coerente) modificando contemporaneamente il set di dati contemporaneamente. Funziona solo perché ha forkcreato un'istantanea coerente che non vede le modifiche apportate dal processo padre.


Al giorno d'oggi sono davvero pochi i demoni, con la maggior parte che non lo fa di serie o che non ha una modalità di uso comune. È un errore biforcarsi che porta a disadattamento e orrori di prontezza , ed è uno degli errori dell'errore fallimentare della desmonizzazione . Finalmente questo errore è ampiamente caduto in disgrazia.
JdeBP,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.