Una llamada, dos retornos
fork() crea un proceso que es copia del que lo llama, y los dos siguen desde ahí. Al terminar sabrás contar procesos y enterrar zombis.
Primero, la idea completa
Mira el video entero o salta a la parte que quieras repasar. Después, cada idea tiene su propia escena para tocarla.
Todo proceso tiene un padre
Un proceso puede crear otros. El que crea es el padre; los nuevos, sus hijos; y los hijos pueden crear los suyos. El resultado es un árbol de procesos. En Linux, la raíz del espacio de usuario es systemd (PID 1), que arranca a todos los demás. El comando ps los lista y pstree dibuja el árbol.
Al crear un hijo hay dos decisiones:
- Ejecución: el padre sigue trabajando al mismo tiempo que su hijo, o espera a que termine.
- Espacio de direcciones: el hijo es un duplicado del padre (mismo programa y mismos datos), o carga un programa nuevo.
Una llamada, dos retornos
En Unix, un proceso nuevo se crea con la llamada al sistema fork(). El hijo es una copia del padre y los dos siguen ejecutando la instrucción siguiente al fork. ¿Cómo saben quién es quién? Por el valor que devuelve: al hijo le devuelve 0, y al padre, el PID del hijo (un número mayor que cero).
pid = fork(); if (pid == 0) { /* soy el hijo */ } else { /* soy el padre */ }
Si el hijo debe ejecutar otro programa, después del fork llama a exec(), que reemplaza su memoria por el programa nuevo. Así lanza la terminal cada comando que escribes.
Un programa llama a fork() varias veces seguidas. Cada proceso que existe en ese momento ejecuta el siguiente fork. ¿Cuántos procesos hay al final?
exit(), kill() y wait()
- Un proceso termina al ejecutar su última instrucción y llamar a
exit(), que devuelve un código de estado a su padre. El sistema operativo recupera todos sus recursos. - También puede terminarlo otro proceso con
kill(). - El padre usa
wait()para esperar a que un hijo termine y recibir su código de salida;wait()devuelve además el PID del hijo que terminó. - Algunos sistemas no permiten hijos sin padre: si el padre termina, terminan todos sus hijos. Es la terminación en cascada.
Zombis y huérfanos
Cuando un hijo termina, sus recursos se liberan, pero su entrada en la tabla de procesos se queda: el padre todavía no ha leído su código de salida. Ese hijo es un zombi. No usa memoria ni CPU, pero ocupa un lugar en la tabla. Desaparece cuando el padre llama a wait(). Como ya terminó, kill no le hace nada.
Si el padre termina sin esperar a sus hijos, estos quedan huérfanos. Unix lo resuelve asignándoles como padre al proceso init (hoy, systemd), que llama a wait() periódicamente y recoge a los zombis que hereda.
Un padre y un hijo. Elige el orden de los acontecimientos y mira qué queda en la tabla de procesos.
Antes de leer la respuesta
En
ps, la columna PPID dice quién es el padre de cada proceso. Un zombi aparece con estado Z y la marca <defunct>.Tu turno: padres, hijos y zombis
La misma terminal, ahora con programas que crean hijos. Usa ps y pstree para ver el árbol, y kill PID para terminar procesos.
Comprueba lo que entendiste
Cada respuesta incorrecta explica por qué parece correcta y en qué falla.