Según Wikipedia (que podría estar equivocado)
Cuando se emite una llamada al sistema fork (), se crea una copia de todas las páginas correspondientes al proceso principal, que el sistema operativo carga en una ubicación de memoria separada para el proceso secundario. Pero esto no es necesario en ciertos casos. Considere el caso cuando un niño ejecuta una "
exec
" llamada al sistema (que se usa para ejecutar cualquier archivo ejecutable desde un programa C) o sale muy pronto después delfork()
. Cuando se necesita el hijo solo para ejecutar un comando para el proceso padre, no hay necesidad de copiar las páginas del proceso padre, ya queexec
reemplaza el espacio de direcciones del proceso que lo invocó con el comando que se ejecutará.En tales casos, se utiliza una técnica llamada copia en escritura (COW). Con esta técnica, cuando se produce una bifurcación, las páginas del proceso principal no se copian para el proceso secundario. En cambio, las páginas se comparten entre el proceso secundario y el proceso primario. Cada vez que un proceso (padre o hijo) modifica una página, se realiza una copia separada de esa página en particular solo para ese proceso (padre o hijo) que realizó la modificación. Este proceso utilizará la página recién copiada en lugar de la compartida en todas las referencias futuras. El otro proceso (el que no modificó la página compartida) continúa utilizando la copia original de la página (que ahora ya no se comparte). Esta técnica se llama copia en escritura ya que la página se copia cuando algún proceso escribe en ella.
Parece que cuando cualquiera de los procesos intenta escribir en la página, se asigna una nueva copia de la página y se le asigna al proceso que generó la falla de la página. La página original se marca como escribible luego.
Mi pregunta es: ¿qué sucede si fork()
se llama varias veces antes de que alguno de los procesos intente escribir en una página compartida?
pmap -XX PID
ocat /proc/PID/smap
.Respuestas:
No pasa nada en particular. Todos los procesos comparten el mismo conjunto de páginas y cada uno obtiene su propia copia privada cuando desea modificar una página.
fuente
El comportamiento de fork () depende de si el sistema * nix tiene una MMU o no. En un sistema que no es MMU (como los primeros PDP-11), la llamada al sistema fork () copiaba toda la memoria de los padres para cada hijo. En un sistema * nix basado en MMU, el núcleo marca todas las páginas no apiladas como R / O y las comparte entre padre e hijo. Luego, cuando cualquiera de los procesos escribe en cualquier página, la MMU atrapa el intento, el núcleo asigna una página que se puede escribir y actualiza las tablas de páginas de MMU para que apunten a la página ahora que se puede escribir. Este comportamiento de Copia en escritura proporciona una aceleración ya que inicialmente solo se necesita asignar y clonar una pila privada para cada proceso secundario.
Si ejecuta algún código primario entre cada llamada fork (), los procesos secundarios resultantes diferirán según las páginas que hayan sido alteradas por el primario. Por otro lado, si el padre simplemente emite múltiples llamadas fork (), por ejemplo, en un bucle, los procesos hijos serán casi idénticos. Si se usa una variable de bucle local, entonces será diferente dentro de la pila de cada niño.
fuente
Cuando el sistema realiza una bifurcación, generalmente (esto puede depender de la implementación) también marca las páginas como de solo lectura y marca el proceso principal como el maestro de estas páginas.
Al intentar escribir en estas páginas, se produce un error de página y el sistema operativo se hace cargo, copiando la lista completa de páginas o solo las modificadas (de nuevo, dependiendo de la implementación), por lo que el proceso de escritura tendrá una copia grabable.
Cuando hay varios procesos bifurcados del mismo, cuando el proceso "maestro" escribe en su memoria, los otros procesos obtienen sus páginas equivalentes copiadas.
fuente