Ya hemos visto cómo trabajar con Linux, tanto desde la interfaz gráfica (GUI) como desde la interfaz de línea de comandos (CLI). Hoy vamos a adentrarnos en los procesos de Linux, que son todas las aplicaciones y tareas que se están ejecutando en el sistema.
¿Qué son los procesos en Linux?
Cuando lanzamos un comando o inicializamos un programa, el sistema operativo pone en funcionamiento (instancia) una serie de tareas. Nos referimos a las tareas que están relacionadas entre sí como “proceso” o “hilo” (thread). Esto significa que un comando o programa puede ejecutar diferentes procesos.
Cada uno de los procesos va a consumir recursos del sistema (memoria, CPU, periféricos…). Por ejemplo, si dos procesos necesitan acceder a una impresora, uno de ellos tendrá que esperar a que el primero termine.
Para gestionar este consumo de recursos, el kernel se encarga de distribuir los procesos, de modo que funcionen de un modo eficiente.
Tipos de procesos en Linux
Podemos categorizar los diferentes procesos en función de sus tipologías. Aquí hay una posible categorización:
- Procesos interactivos. Por ejemplo, la consola o un programa tipo el navegador o un editor de texto. El usuario es el responsable de iniciarlos.
- Hilos del Kernel. Al contrario que los interactivos, son procesos que inicia el kernel, no el usuario. Gestionan otros procesos e hilos para garantizar su ejecución ordenada.
- Lotes de procesos. Se trata de procesos que se registran para ir ejecutándose siguiendo un esquema FIFO (First In, First Out). Por ejemplo, la actualización de la base de datos al lanzar updatedb.
- Daemons. Se trata de procesos que se ejecutan permanentemente. Por ejemplo, los servicios http o ssh.
- Hilos. Son procesos ligeros, que se ejecutan a raíz de un proceso principal. El proceso principal puede desplegar varios hilos, y el hecho de que un hilo haya concluido su ejecución no supone que el proceso principal haya terminado. Por ejemplo, gnome-terminal-server.
Estados y planificación
El scheduler (planificador) es una función crítica del kernel, que se encarga de planificar qué procesos deben ejecutarse en base a su prioridad, el tiempo que han consumido y el que todavía necesitan para concluirse.
Cada proceso está identificado por un process ID (PID) único, que hará seguimiento del estado del proceso, su consumo de recursos (CPU, memoria…) y otros detalles. A nivel de identificación del proceso también contamos con un Parent Process ID o PPID (ID del proceso que inició este proceso) y de un Thread ID o TID (ID del hilo, que diferirá del PID en procesos con múltiples hilos).
El scheduler va cambiando el estado de un proceso:
- running implica que el proceso está ejecutándose, o bien a la espera de una cesión de recursos para ejecutarse. Estos procesos residen en la cola de ejecución (run queue). En máquinas con varias CPUs o núcleos, existe una run queue por cada CPU o núcleo.
- sleep indica que el proceso está esperando a que ocurra algo antes de volver a ejecutarse. Por ejemplo, la recepción de una respuesta por parte de otro servicio o el input de un usuario.
- zombie. Se trata de procesos hijos o derivados, que ya han terminado, pero como el padre todavía no ha preguntado por su estado, siguen presentes en la lista de procesos del sistema.
La ejecución de los procesos
Como ves, lo habitual es que haya varios procesos funcionando o en la run queue simultáneamente. Sin embargo, cada CPU o núcleo solo puede encargarse de una tarea a la vez. ¿Cómo gestiona los múltiples procesos, entonces?
Básicamente jerarquiza los procesos mediante un nice value o niceness (en un rango entre -20 y 19. Cuanto más bajo sea este nivel, más alta será la prioridad del proceso. También se utiliza otra jerarquización mediante el valor real-time priority, reservado a tareas que requieren cierta sincronicidad.
El comando ps nos permite mostrar los procesos del sistema (con la opción lf nos mostrará también su prioridad), y mediante el comando renice podemos reasignar el valor de niceness de un proceso.
¿Cómo terminar un proceso?
Si necesitamos terminar un proceso podemos utilizar los siguientes comandos:
kill -SIGKILL <pid>
kill -9 <pid>
Recuerda que debes tener permisos de super usuario (sudo) o solo podrás terminar tus propios procesos.
Cómo controlar los procesos de Linux
Podemos medir los procesos de Linux mediante la métrica load average, que indica la media de tiempo que los procesos han estado en cola, durmiendo o en ejecución. Para ello tenemos disponible los comandos:
- w
- top
- uptime
El load average muestra tres métricas. Estas representan el consumo de la CPU que ha realizado el proceso, respectivamente, en el último minuto, los últimos 5 minutos y los últimos 15 minutos.
Recuerda que los datos hacen referencia a una única CPU. Esto significa que el valor máximo será de 1.0 en máquinas con una CPU, y de 4.0 en máquinas con 4 núcleos.
Si la carga se mide en tiempos medios es porque es normal que un proceso pegue un acelerón y consuma más recursos en un momento dado. Lo que no lo es, es que el proceso consuma muchos recursos de forma sostenida en el tiempo.
Los procesos de fondo (background)
Linux permite la ejecución de procesos secundarios para no interrumpir el uso de la consola. Ten en cuenta que cuando abres un proceso en la terminal, esta queda inutilizada hasta que el proceso haya terminado. Esta es la forma de ejecución por defecto, pero añadiendo & a continuación de un comando podemos llevarlo al background para que no nos interrumpa.
También podemos utilizar CTRL-Z para llevarnos un proceso del foreground al background (en lugar de CTRL-C, que lo que hace es terminarlo). Por su parte, los comandos bg y fg nos permiten llevar procesos al background y al foreground respectivamente. Y el comando jobs nos indica qué procesos están registrados en el background.
Ten en cuenta que si te llevas un proceso al background con CTRL-Z puede quedar detenido. Si a continuación lanzas el comando jobs verás que está registrado en el background, pero con estado “stopped”. Para reiniciarlo deberás ejecutar el comando bg seguido de su identificador. En caso de querer traértelo al foreground el comando a ejecutar será fg.
Cómo gestionar procesos en Linux
El comando ps (process status) nos permite comprobar los estados de los procesos activos en estos momentos. Disponemos de otros comandos, como he comentado antes (w o top, por ejemplo). Además, podemos personalizar el output obtenido del comando ps utilizando opeciones como -ef o -eLf, que muestran más detalles de cada proceso y/o hilo.
Ten en cuenta que el comando ps acepta opciones con y sin guiones, lo que en ocasiones lo hace confuso. De hecho, el mismo comando con y sin guion puede encargarse de tareas diferentes.
Otro comando útil para ver los procesos activos es pstree, que nos los mostrará en forma de diagrama de árbol para visualizar las relaciones entre cada uno de los procesos.
Programando procesos
En Linux podemos programar procesos con la utilidad at. Otra opción para programar la ejecución de un proceso es utilizar cron. Con el comando crontab -e podemos lanzar el editor de tareas cron.
El problema de las tareas cron es que no se ejecutarán si la máquina no está en funcionamiento. Por eso, las distribuciones actuales de Linux tienden a llevar otra utilidad: anacron.
Si lo único que necesitamos es que la ejecución de un proceso se paralice durante un tiempo determinado, podemos utilizar el comando sleep.
Resumen
- Los procesos se encargan de realizar las tareas que necesita el sistema. Pueden ocupar un hilo de ejecución o varios, y ser interactivos o no.
- Podemos identificar los procesos por su PID, y utilizar comandos como ps o top para conocer su estado. Una de las métricas más importantes que obtendremos será el load average, que determina el tiempo de ejecución que ha ocupado el proceso durante un período determinado.
- Disponemos de funcionalidades como at, cron y sleep para programar o diferir la ejecución de procesos.
Comandos y shortcuts
- ps - muestra los procesos del sistema.
- ps lf - muestra los procesos del sistema y su prioridad.
- renice +-x <PID> - reasigna un valor de niceness al sistema.
- kill -SIGKILL <pid> - Termina un proceso.
- kill -9 <pid> - Termina un proceso.
- uptime - Nos indica el tiempo que ha estado la máquina en funcionamiento.
- w - Proporciona información sobre los procesos y su load average.
- top - proporciona información sobre los procesos con mayor consumo de recursos.
- CTRL-Z
- &
- bg
- fg
- jobs
- pstree
- at
- cron
- crontab -e
- anacron
- sleep