2013-03-23 2 views
5

Su Linux, se fork() e le uscite del processo forche (figlio) sono tutte le pagine di memoria virtuale ancora contrassegnate come copia-su-scrittura nel genitore?Se fork() e le uscite del processo forfettario (figlio) sono tutte le pagine della VM ancora contrassegnate come COW nel genitore?

Penso che le pagine rimarranno contrassegnate come COW come qualsiasi altra cosa sarebbe probabilmente eccessivamente costosa da implementare, probabilmente conteggi di ref per pagina e altri costosi libri contabili. Ma mi chiedevo l'altro giorno, se forzo un processo per eseguire del codice in una "fotografia stabile" del processo corrente. Cosa succede quando termina il processo figlio? Tutte le pagine di memoria del genitore rimangono contrassegnate come copy-on-write? Ciò significa che la biforcazione in un processo con molta memoria virtuale (ad esempio 128 GB +) solo per eseguire qualche codice per alcuni minuti causerebbe un rallentamento delle prestazioni nel processo principale, per ore o persino giorni dopo (per non parlare della stessa chiamata a forcella che non sarebbe a buon mercato.)

sono solo curioso di sapere cosa il comportamento reale è su Linux (e non ho idea di come avrei potuto testarlo.)

+0

Non sono sicuro, ma dovresti usare 'posix_spawn', non' fork', per eseguire programmi esterni. –

+0

IIRC, COW è impostato su * entrambi * le pagine padre e figlio. Il primo a venire ottiene la pagefault e la pagina è clonata (e nessuna delle pagine clonate ha più il COW impostato) BTW: potresti guardare la fonte. È open source, lo sai ... – wildplasser

risposta

8

a parte la scrittura copy-on- bit c'è anche un conteggio dei riferimenti nella tabella delle pagine. Pertanto, quando un figlio si biforca, tutte le pagine non private del genitore sono contrassegnate come COW e il conteggio dei riferimenti viene incrementato.

Quindi mentre il processo figlio è in esecuzione e il genitore scrive una pagina, si otterrà un errore di pagina e la pagina verrà copiata come ci si aspetterebbe e il conteggio dei riferimenti diminuirà. Quando il bambino esce, riduce tutti i suoi riferimenti di pagina con uno, e le pagine con il numero di riferimento zero vengono gettati via.

Ora quando il genitore scrive una pagina con il bit COW impostato e un conteggio di riferimento di uno, il bit COW viene semplicemente ignorato.

+0

Ora è dolce! – Eloff

0

Il kernel contrassegna tutte le pagine condivise come protette da scrittura, risultando in tal modo un'eccezione se uno tenta di modificarne una. Il duplicato viene creato ed è contrassegnato come scrivibile (quindi non più eccezioni), mentre l'originale rimane protetto da scrittura.

Se l'originale è stato scritto, si verifica un'altra eccezione, ma il kernel vedrà che la pagina non è condivisa da nessun altro processo e quindi contrassegnerà anche quella come scrivibile. Quando un processo termina, tutte le sue pagine sono rilasciate, e quindi il kernel rimuoverà efficacemente lo stato COW da ogni pagina del genitore quando viene modificato.