2011-12-03 7 views
10

Sto leggendo su fork e exec per un esame, e il mio libro dice che ogni volta che è necessario eseguire un nuovo (diverso) processo in sistemi unix, si forchetta il processo corrente seguito da uno execve.La sequenza exec di unix fork è davvero costosa come sembra?

Tuttavia, si dice anche che ogni volta che viene chiamato fork, l'intera immagine di memoria del genitore viene copiata nel nuovo processo.

Quindi la mia domanda è: cosa succede se si dispone di un processo con un'immagine di memoria veramente grande e si desidera solo eseguire un nuovo processo? Non è uno spreco di risorse copiare tutti i dati dal processo principale se hai intenzione di sostituirlo immediatamente?

+0

+1 buona domanda, grazie. Spesso mi chiedo come le risposte vengano premiate molto più della domanda. Senza la domanda non ci fu risposta. E la domanda era nella mia testa :) – humanityANDpeace

risposta

5

In genere la forcella non copia effettivamente tutta la memoria, ma utilizza una "copia su scrittura" che significa che finché la memoria non viene modificata vengono utilizzate le stesse pagine. Tuttavia, per evitare di non avere memoria sufficiente in seguito (se il processo scrive nella memoria) è necessario allocare una quantità di memoria sufficiente.

Ciò significa che la biforcazione da processi di grandi dimensioni su sistemi che non consentono la memoria di overcommitting deve essere disponibile. Quindi, se si dispone di un fork di processo da 8 GB, per almeno un breve periodo di tempo devono essere disponibili 16 GB.

Vedere anche vfork e posix_spawn per altre soluzioni.

+1

Questa risposta è sfortunatamente sbagliata - l'overcommitting non fa parte di unix, ma è un'estensione di alcuni sistemi.I più comuni (ad esempio Linux) non richiedono, per impostazione predefinita, che siano disponibili 16 GB completi sulla forcella. –

+1

Anche se un kernel del sistema operativo desidera verificare che sia disponibile memoria sufficiente, ciò non significa che sarebbe necessario disporre di tutti gli 8 GB disponibili poiché molte di queste pagine possono essere condivise in virtù delle sole pagine di sola lettura e lettura/esecuzione. – nategoose

1

Nessuna copia di memoria viene eseguita a meno che uno dei processi non modifichi la memoria, nel qual caso la pagina verrà copiata e se si sta chiamando exec() nel processo figlio subito dopo il richiamo di fork(), non viene eseguita alcuna copia fatto.

In realtà penso che exec() venga sempre chiamato prima che il processo padre scriva mai in memoria, il processo figlio viene eseguito sempre per primo.

Penso che si può trovare questo in programmazione avanzata in UNIX

+0

Pensi di sbagliare, il genitore può continuare prima del bambino, sia in teoria che in pratica. Inoltre, ancora più importante, una copia di memoria è ancora fatta. –

2

Alcuni sistemi che sono o molto vecchi (inizio unix), o molto speciali (MMU-meno Linux) o verfy schifosi (finestre tramite cygwin) è necessario fare una copia completa di tutte le pagine ("ogni byte") sulla forcella, quindi il potenziale è lì.

I moderni kernel unix non copiano tutta la memoria del processo, scegliendo invece di creare una copia virtuale. Sebbene ciò comporti solo una frazione della copia (le tabelle delle pagine devono essere copiate), questo può essere ancora molti megabyte e richiede molto tempo.

Quindi la risposta è sì in generale, ma le implementazioni più moderne utilizzano l'hardware per realizzare una copia virtuale veloce, ma anche quella copia virtuale non è gratuita.

Sia i vecchi che alcuni sistemi moderni implementano una chiamata speciale vfork() che presenta dei limiti piuttosto rigidi (anche se meno rigidi rispetto ai requisiti del sistema POSIX per vfork) ma evitano questa copia, per motivi di prestazioni.

Per dare alcuni numeri reali, sul mio sistema GNU/Linux, posso fork + exit 1340 volte al secondo da un processo da 20 MB, ma solo 235 volte/s su un processo da 2000 MB. In entrambi i casi è più veloce su vfork + execve, il che è alquanto intuitivo, perché molte persone pensano "fork is fast" e "execve deve essere lento".