Sobes.tech
Middle

¿Qué sucede con la memoria del proceso cuando creamos una copia de él usando la llamada al sistema fork en el sistema operativo Linux?

sobes.tech AI

Respuesta de la IA

Al llamar a fork(), el núcleo del sistema operativo crea un nuevo proceso, un proceso hijo, que es casi una copia exacta del proceso padre.

Desde el punto de vista de la memoria, sucede lo siguiente:

  1. Espacio de direcciones virtuales: El proceso hijo recibe su propio espacio de direcciones virtuales separado, idéntico al del padre en el momento de la llamada a fork(). Esto significa que el proceso hijo "ve" los mismos rangos de direcciones y tiene la misma estructura de segmentos (código, datos, pila, montón) que el padre.

  2. Memoria física y Copy-on-Write (CoW): Inicialmente, los procesos padre e hijo comparten las mismas páginas de memoria física. Esta es una optimización conocida como "Copy-on-Write" (CoW). La memoria física solo se copia cuando uno de los procesos intenta modificar el contenido de una página.

    • Si el proceso padre o hijo escribe datos en una página que antes era compartida, el núcleo crea una copia nueva de esa página de memoria física para el proceso que realiza la escritura. El otro proceso continúa usando la versión antigua de la página.
    • Si los procesos solo leen datos, continúan usando la misma página de memoria física compartida.
  3. Manejadores de archivos: Los descriptores de archivos abiertos se heredan en el proceso hijo. Ambos procesos comparten los punteros a los desplazamientos en el archivo.

  4. Otros recursos: Otros recursos, como manejadores de señales, directorio de trabajo actual, etc., también se copian o heredan.

Aquí una ilustración simplificada:

Antes de fork():

+-------------------+
| Proceso Padre     |
| +--------------+  |
| | Memoria Virtual | |
| | (Pila, Montón, ...) | |
| +--------------+  |
|      |            |
|      V            |
| +--------------+  |
| | Memoria Física | |
| +--------------+  |
+-------------------+

Inmediatamente después de fork() (CoW):

+-----------------------+   +-----------------------+
| Proceso Padre         |   | Proceso Hijo          |
| +-------------------+ |   | +-------------------+ |
| | Memoria Virtual    | |   | | Memoria Virtual    | |
| | (La misma estructura)| |   | | (La misma estructura)| |
| +-------------------+ |   | +-------------------+ |
|        |              |   |        |              |
|        V              |   |        V              |
| +-------------------+ |   | +-------------------+ |
| | Memoria Física     | |   | | Memoria Física     | |
| | (Algunas páginas compartidas)| | | (Algunas páginas compartidas)| |
| +-------------------+ |   | +-------------------+ |
+-----------------------+   +-----------------------+
          |                            |
          +----------------------------+
                Páginas físicas iniciales compartidas

Después de escribir en una de las páginas (CoW activado):

+-----------------------+   +-----------------------+
| Proceso Padre         |   | Proceso Hijo          |
| +-------------------+ |   | +-------------------+ |
| | Memoria Virtual    | |   | | Memoria Virtual    | |
| |                   | |   | |                   | |
| +-------------------+ |   | +-------------------+ |
|        |              |   |        |              |
|        V              |   |        V              |
| +-------------------+ |   | +-------------------+ |
| | Memoria Física     | |   | | Memoria Física     | |
| | (Páginas físicas separadas)| | | (Páginas físicas separadas)| |
| +-------------------+ |   | +-------------------+ |
+-----------------------+   +-----------------------+

Es importante entender que, aunque inmediatamente después de fork() el espacio de direcciones virtuales es idéntico, cualquier cambio en la memoria de uno de los procesos (escribir en variables, asignar/liberar memoria en el montón) no afecta a la memoria del otro proceso gracias al mecanismo CoW. Son procesos completamente independientes.