Come funzionano fork e exec?


17

Non ho molta esperienza, sto solo cercando di essere coinvolto nei processi come interpretano l'hardware a livello di utente.

Quindi quando un comando viene lanciato da una shell, ne fork()eredita un processo figlio e exec()carica il processo figlio nella memoria ed esegue.

  1. Se il processo figlio contiene tutti gli attributi del processo genitore (che è il processo originale), allora qual è la necessità di questo processo figlio? Anche il processo originale avrebbe potuto essere caricato in memoria.
  2. Questo forke questo execconcetto si applicano a tutto il programma eseguibile in UNIX? Ti piace lo script shell anche o solo per i comandi? Si applica anche ai comandi integrati della shell?
  3. Quando viene utilizzato il concetto di copia su scrittura se eseguirò un comando / script?

Ci scusiamo per aver fatto molte domande alla volta, ma tutte queste domande mi vengono subito in mente quando penso a qualsiasi esecuzione di comando.


Non dirò che questo è un duplicato, ma penso che alcune delle vostre domande abbiano una risposta qui: unix.stackexchange.com/questions/136637/… e nell'altra risposta collegata nella parte superiore di quella.
Riccioli d'oro,

Risposte:


22

Quindi quando un comando viene lanciato da una shell, fork () eredita un processo figlio da esso ed exec () carica il processo figlio nella memoria ed esegue.

Non proprio. fork()clona il processo corrente, creando un figlio identico. exec()carica un nuovo programma nel processo corrente, sostituendo quello esistente.

La mia domanda è:

Se il processo figlio contiene tutti gli attributi del processo genitore (che è il processo originale), allora qual è la necessità di questo processo figlio? Anche il processo originale avrebbe potuto essere caricato in memoria.

La necessità è perché il processo genitore non vuole ancora terminare; vuole che un nuovo processo si interrompa e faccia qualcosa allo stesso tempo che continua anche a eseguire.

Questo concetto fork e exec si applica a tutto il programma eseguibile in UNIX? Come per lo script shell anche o solo per i comandi? Si applica anche ai comandi integrati della shell?

Per i comandi esterni, la shell fa in fork()modo che il comando venga eseguito in un nuovo processo. I builtin sono gestiti direttamente dalla shell. Un altro comando notevole è exec, che dice alla shell exec()il programma esterno senza prima fork()ing. Questo significa che la shell stessa viene sostituita con il nuovo programma, e quindi non è più lì per quel programma a cui tornare quando esce. Se dici, exec trueallora /bin/truesostituirà la tua shell e uscirà immediatamente, lasciando nulla in esecuzione nel tuo terminale, quindi si chiuderà.

quando viene usato il concetto di copia su scrittura se eseguirò un comando / script?

Già nell'età della pietra, in fork()realtà dovevo copiare tutta la memoria del processo di chiamata nel nuovo processo. Copia su scrittura è un'ottimizzazione in cui le tabelle delle pagine sono impostate in modo che i due processi inizino a condividere tutta la stessa memoria e solo le pagine scritte da entrambi i processi vengano copiate quando necessario.


4
"Per quasi tutti i comandi, la shell esegue un fork () in modo che il comando venga eseguito in un nuovo processo. Se quel comando è incorporato, il bambino non ha bisogno di eseguire () un programma separato." Buona risposta, ma questa parte dovrebbe essere modificata. La shell non si biforca quando si eseguono builtin. Esegue quelli direttamente nel processo di shell attivo. Questo è l'unico modo in cui i builtin gradiscono cdo readpotrebbero funzionare. La mancanza di biforcazione rende i builtin molto più veloci dei comandi esterni.
John Kugelman supporta Monica il

6
  1. Per alcuni programmi, il processo figlio fa una cosa (leggere da una porta seriale, scrivere sul terminale) e il processo genitore continua a fare qualcos'altro (leggere dal terminale, scrivere sulla porta seriale). Un altro esempio classico è che il processo figlio esegue un checkpoint di qualsiasi calcolo a lungo termine in corso. Principalmente, il processo figlio esegue alcune impostazioni, come la modifica della directory, il ripristino dei gestori di segnale o il ripristino dei descrittori di file, quindi chiama execve()per sovrapporsi con codice diverso.
  2. fork()e exec()si applicano a tutti gli eseguibili - in effetti, insieme a argc e argv, e pipe, fork ed exec sono ciò che distingue Unix dagli altri sistemi operativi. fork()Esistono alcune specializzazioni o generalizzazioni , come BSD vfork(), Plan 9 rfork()e Linux ' clone(), ma il principale rimane lo stesso.
  3. "copy on write" non si presenta davvero all'utente, è più una tecnica per ottimizzare la creazione di un processo figlio e durante la sua esecuzione. Lo stack di chiamate e l'heap (memoria allocata con malloc()o anche variabili dell'ambito statiche o globali) potrebbero essere "copia in scrittura". Quando un processo figlio viene creato con afork()call, il kernel imposterebbe il processo figlio in modo da avere esattamente le stesse pagine di memoria di heap e stack del processo genitore. Se l'hardware (unità di gestione della memoria) rileva una scrittura dell'heap o dello stack, il kernel otterrebbe una nuova pagina fisica di memoria, copia la pagina del genitore nella nuova pagina e mappa quella nuova pagina nello stack o heap del processo figlio. Ciò costituisce un'ottimizzazione in quanto il kernel impiega meno tempo a impostare i mapping delle pagine rispetto a copiare completamente stack e heap per il processo figlio.

Grazie Bruce per la tua risposta. Ma così tante cose che hai detto qui che mi passano per la testa. Non ho molta conoscenza di queste cose ... Cercherò di far funzionare queste funzioni che hai menzionato. Grazie mille..!!
PriB

4
Se il processo figlio contiene tutti gli attributi del processo genitore (che è il processo originale), allora qual è la necessità di questo processo figlio? Anche il processo originale avrebbe potuto essere caricato in memoria.

A questa domanda viene fornita una risposta molto illustrativa dando uno sguardo alle prime implementazioni Unix che dovevano funzionare con severi vincoli di memoria e che avevano un solo processo di esecuzione nello spazio di memoria / indirizzo alla volta.

Il multitasking è stato ottenuto scambiando un processo su disco e scambiando un altro processo.

Ora la forkchiamata di sistema era quasi la stessa: ha scambiato un processo su disco, ma invece di scambiare un altro processo, ha dato alla copia in memoria un altro ID processo e vi ha restituito. E quello era un momento opportuno per questo processo, execdopo tutto, decidere di passare a un altro eseguibile.

fork+ in exectal modo non si è effettivamente verificato un notevole sovraccarico per la deposizione delle uova: in ogni caso è stato necessario sostituire il processo su disco e disporre comunque della vecchia immagine di processo in posizioni di memoria praticabili.

Con quantità crescenti di memoria disponibile e unità di gestione della memoria e molteplici processi in memoria, il costo inizialmente trascurabile di un fork è diventato un po 'più fastidioso per alcune architetture: così vforkè nato.


2

Per renderlo il più semplice possibile, userò un'analogia. Facciamo una torta!

Prendiamo il ricettario, iniziamo a leggere e ci sistemiamo su una torta di rabarbaro alla fragola (la mia preferita), con una crosta fatta a mano. Quasi tutto ciò di cui abbiamo bisogno è in cucina tranne le uova e la frutta, ma poiché viviamo in una fattoria e la frutta è di stagione, questo non è un problema. il problema è che il forno è rotto e non c'è abbastanza tempo per fare tutto. Non sarebbe bello avere più di uno di me?

fork () per il salvataggio. Ora ci sono due di me. e entrambi andiamo in cucina per iniziare a preparare la crosta di torta. oops. Quindi guardiamo al ritorno dal fork. Ho un gran numero che ha zero, quindi vado in cucina mentre si dirige verso il pollaio e il giardino. Mentre passo davanti al forno bivio di nuovo (), guardo il valore di ritorno: bummer ho zero. Continua con la farina mentre fisso il forno rotto. Apro la porta, nessuna luce, chiudo la porta. Qualcuno sa come riparare un forno?

exec () in soccorso. Prendo il voltmetro sulla cintura degli attrezzi, la lampadina potrebbe essere diagnostica, quindi controllo la potenza, infatti è scattato l'interruttore, una soluzione semplice. mentre cammino verso il pannello degli interruttori, vedo un compagno che raccoglie rabarbaro. Che schifo! Preferisco la torta di seta al cioccolato.

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.