La chiamata di sistema UNIX per la creazione del processo, fork(), crea un processo figlio copiando il processo padre. La mia comprensione è che questo è quasi sempre seguito da una chiamata a exec() per sostituire lo spazio di memoria del processo figlio (incluso il segmento di testo). Copiare lo spazio di memoria del genitore in fork() mi è sempre sembrato uno spreco (anche se mi rendo conto che lo spreco può essere ridotto al minimo facendo i segmenti di memoria copy-on-write in modo che vengano copiati solo i puntatori). Ad ogni modo, qualcuno sa perché questo approccio di duplicazione è necessario per la creazione del processo?
Risposta accettata:
È per semplificare l'interfaccia. L'alternativa a fork e exec sarebbe qualcosa come la funzione CreateProcess di Windows. Nota quanti parametri CreateProcess has, e molti di essi sono struct con ancora più parametri. Questo perché tutto potresti voler controllare il nuovo processo deve essere passato a CreateProcess . Infatti, CreateProcess non dispone di parametri sufficienti, quindi Microsoft ha dovuto aggiungere CreateProcessAsUser e CreateProcessWithLogonW.
Con il fork/exec modello, non hai bisogno di tutti quei parametri. Al contrario, alcuni attributi del processo vengono mantenuti in exec . Questo ti permette di fork , quindi modifica gli attributi di processo che desideri (utilizzando le stesse funzioni che useresti normalmente) e poi exec . In Linux, fork non ha parametri e execve ne ha solo 3:il programma da eseguire, la riga di comando da dargli e il suo ambiente. (Ci sono altri exec funzioni, ma sono solo wrapper di execve fornito dalla libreria C per semplificare i casi d'uso comuni.)
Se vuoi avviare un processo con una directory corrente diversa:fork , chdir , exec .
Se vuoi reindirizzare stdin/stdout:fork , chiudi/apri file, exec .
Se vuoi cambiare utente:fork , setuid , exec .
Tutte queste cose possono essere combinate secondo necessità. Se qualcuno esce con un nuovo tipo di attributo di processo, non devi cambiare fork e exec .
Come accennato in precedenza, la maggior parte degli Unix moderni usa il copy-on-write, quindi fork non comporta un sovraccarico significativo.