[Ripeterò parte della mia risposta da qui .]
Perché non avere semplicemente un comando che crea un nuovo processo da zero? Non è assurdo e inefficiente copiarne uno che verrà sostituito immediatamente?
In effetti, probabilmente non sarebbe altrettanto efficiente per alcuni motivi:
La "copia" prodotta da fork()
è un po 'di un'astrazione, dal momento che il kernel usa un copy-on-write del sistema ; tutto ciò che deve davvero essere creato è una mappa di memoria virtuale. Se la copia chiama immediatamente exec()
, la maggior parte dei dati che sarebbero stati copiati se fosse stata modificata dall'attività del processo non deve mai essere effettivamente copiata / creata perché il processo non fa nulla che richieda il suo utilizzo.
Vari aspetti significativi del processo figlio (ad esempio, il suo ambiente) non devono essere duplicati individualmente o impostati sulla base di un'analisi complessa del contesto, ecc. Si presume che siano gli stessi di quelli del processo chiamante e questo è il sistema abbastanza intuitivo che conosciamo.
Per spiegare un po 'di più il numero 1, la memoria che viene "copiata" ma a cui non si accede successivamente non viene mai realmente copiata, almeno nella maggior parte dei casi. Un'eccezione in questo contesto potrebbe essere se si è proceduto a un fork di un processo, quindi il processo padre è stato chiuso prima che il figlio si sostituisse exec()
. Dico che potrebbe essere perché la maggior parte dei genitori potrebbe essere memorizzata nella cache se c'è abbastanza memoria libera, e non sono sicuro di quanto questo sarebbe sfruttato (che dipenderebbe dall'implementazione del sistema operativo).
Ovviamente, ciò non rende in superficie più efficiente l' uso di una copia rispetto all'utilizzo di una lavagna vuota, tranne per il fatto che "la lavagna vuota" non è letteralmente nulla e deve comportare un'allocazione. Il sistema potrebbe avere un modello di processo vuoto / nuovo generico che copia allo stesso modo, 1 ma che quindi non salverebbe realmente nulla rispetto al fork di copia su scrittura. Quindi il n. 1 dimostra solo che l'utilizzo di un "nuovo" processo vuoto non sarebbe più efficiente.
Il punto 2 spiega perché l'uso della forcella è probabilmente più efficiente. L'ambiente di un bambino viene ereditato dal suo genitore, anche se è un eseguibile completamente diverso. Ad esempio, se il processo padre è una shell e il figlio un browser Web $HOME
è sempre lo stesso per entrambi, ma poiché entrambi potrebbero successivamente modificarlo, devono essere due copie separate. Quello nel bambino è prodotto dall'originale fork()
.
1. Una strategia che potrebbe non avere molto senso letterale, ma il mio punto è che la creazione di un processo implica più che copiare la sua immagine in memoria dal disco.