Procesos en Linux, estados y prioridades

Publicado por Diego Córdoba en

Hoy aprenderemos los conceptos de gestión de los procesos en linux y las herramientas para administrar listas de procesos y prioridades.


Los procesos en Linux, o en cualquier sistema operativo *nix, son creados en base a un proceso ya existente mediante un mecanismo de clonación, o «fork«. Hoy hablaremos específicamente de gestión de procesos en Linux.

Un proceso en Linux genera un nuevo proceso para que realice una tarea determinada, y este nuevo proceso es considerado proceso «hijo» del proceso anterior, al que llamaremos «padre«.

Esta estructura de procesos padres e hijos forman un árbol jerárquico de procesos, en los que podemos distinguir a hilos del kernel, al proceso init, a systemd, y al resto de los procesos del sistema, descolgados de algún otro proceso, lo que nos da una idea de qué proceso generó a cuál otro.

Un ejemplo de la estructura jerárquica podemos verlo con ps o pstree:

diego@cryptos:~$ ps fax
  PID TTY      STAT   TIME COMMAND
[...]
  262 ?        S<     0:00  \_ [kpsmoused]
  405 ?        S      0:10  \_ [jbd2/sda5-8]
  406 ?        S<     0:00  \_ [ext4-rsv-conver]
  408 ?        S<     0:00  \_ [kvm-irqfd-clean]
21776 ?        S<     0:00  \_ [dio/sda5]
10261 ?        S      0:00  \_ [kworker/3:2]
10268 ?        S      0:00  \_ [kworker/1:2]
10277 ?        S      0:00  \_ [kworker/2:2]
14024 ?        S      0:00  \_ [irq/31-mei_me]
14025 ?        S      0:00  \_ [kworker/2:0]
14034 ?        S      0:00  \_ [kworker/3:0]
14038 ?        S      0:00  \_ [kworker/1:1]
23538 ?        S      0:00  \_ [kworker/0:0]
23767 ?        S      0:00  \_ [kworker/u8:0]
24313 ?        S      0:00  \_ [kworker/u8:2]
24395 ?        S      0:00  \_ [kworker/0:1]
24591 ?        S      0:00  \_ [kworker/u8:1]
24655 ?        S      0:00  \_ [kworker/1:0]
24742 ?        S      0:00  \_ [kworker/3:1]
24755 ?        S      0:00  \_ [kworker/0:2]
    1 ?        Ss     0:02 /sbin/init
  195 ?        Ss     0:00 /usr/lib/systemd/systemd-journald
  229 ?        Ss     0:00 /usr/lib/systemd/systemd-udevd
  423 ?        Ss     0:01 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  426 ?        Ss     0:00 /usr/lib/systemd/systemd-logind
  506 ?        Ss     0:00 login -- diego
  516 tty1     Ss+    0:00  \_ -bash
  549 tty1     S+     0:00      \_ xinit /home/diego/.xinitrc -- /etc/X11/xinit/xserverrc :0 vt1 -auth /tmp/serverauth.
  550 tty1     S    101:04          \_ /usr/lib/xorg-server/Xorg -nolisten tcp :0 vt1 -auth /tmp/serverauth.294QcjxI77
  553 tty1     Sl     0:01          \_ /usr/bin/lxsession -s LXDE -e LXDE
  585 tty1     S      0:42              \_ openbox --config-file /home/diego/.config/openbox/lxde-rc.xml
  587 tty1     Sl     0:00              \_ lxpolkit
  588 tty1     Sl     4:24              \_ lxpanel --profile LXDE
 1006 tty1     Sl   1063:25              |   \_ firefox
 1681 tty1     Sl    30:31              |   \_ /usr/lib/chromium/chromium
 1683 tty1     S      0:00              |   |   \_ /usr/lib/chromium/chrome-sandbox /usr/lib/chromium/chromium --type=z
 1684 tty1     S      0:00              |   |   |   \_ /usr/lib/chromium/chromium --type=zygote
 1686 tty1     S      0:00              |   |   |       \_ /usr/lib/chromium/chrome-sandbox /usr/lib/chromium/nacl_help
 1687 tty1     S      0:00              |   |   |       |   \_ /usr/lib/chromium/nacl_helper
 1689 tty1     S      0:00              |   |   |       \_ /usr/lib/chromium/chromium --type=zygote
 1755 tty1     Sl     0:04              |   |   |           \_ /usr/lib/chromium/chromium --type=renderer --force-field
 1761 tty1     Sl     0:08              |   |   |           \_ /usr/lib/chromium/chromium --type=renderer --force-field
 1815 tty1     Sl     7:09              |   |   |           \_ /usr/lib/chromium/chromium --type=renderer --force-field
[...]

PID, el identificador de proceso en Linux

El PID, o Process ID, es un número entero que identifica unívocamente a cada proceso en una tabla de procesos administrada por el kernel Linux. Esta tabla de procesos mantiene una entrada por cada uno de los procesos que están en ejecución en el sistema en el momento actual. Esa tabla es, precisamente, la que se consulta con comandos como ps o pstree.

Uno de los datos almacenados, es el pid, o process-id que, como hemos visto en un artículo anterior, nos facilita la terminación de procesos que no responden, o le permite al sistema operativo comunicar procesos usando IPC, entre otras tareas.

Kernel Multitarea

El kernel Linux es un kernel de sistema operativo que permite la multitarea. Hay que tener en cuenta que el procesador solamente puede estar procesando un proceso a la vez en cada uno de sus núcleos, o «cores«.

¿Cómo logra Linux simular la multitarea? ¿Cómo es posible, de esta forma, que podamos estar ejecutando varias aplicaciones «simultáneamente» con un solo core?

La respuesta es simple. El kernel del sistema operativo le da un tiempo de procesamiento a un proceso, luego lo retira de los registros del procesador, e introduce a otro proceso en su lugar. Este intercambio se lleva a cabo con una frecuencia altísima que permite simular una multitarea real a nivel de usuario.

El estado de los procesos en Linux

En Linux los procesos pueden estar en diferentes estados, simbolizados mediante una letra en la salida del comando htop/top.

 procesos en linux estados

Los estados principales en los que un proceso puede estar, y que en la salida de un htop están etiquetados en la columna «S«(status), son los siguientes:

  • D    Uninterruptible sleep – Espera ininterrupible, generalmente el proceso se encuentra esperando una operación de entrada/salida con algún dispositivo.
  • R    Running – Corriendo, el proceso se encuentra corriendo en el procesador.
  • S    Interruptible sleep, espera interrumpible, el proceso se encuentra esperando a que se cumpla algún evento, por ejemplo, que el planificador de procesos del kernel lo planifique para su ejecución.
  • T    Stopped, detenido, un proceso que ha sido detenido mediante el envío de alguna señal generalmente.
  • Z    Defunct (“zombie”) process, proceso terminado, pero cuyo padre aún sigue «vivo» y no ha capturado el estado de terminación del proceso hijo, y por consiguiente, no lo ha eliminado de la tabla de procesos del sistema. En definitiva, un proceso zombie es un proceso que «murió», pero «sigue estando» en la tabla de procesos del sistema. En algún otro artículo hablaremos específicamente de estados de procesos, zombies, y cómo detectarlos.

Procesos en Linux y prioridades

Ahora bien, cuando el kernel, mediante su administrador de procesos, retira un proceso del procesador, ¿cómo decide qué proceso deberá ingresar?

Eso lo decide mediante un cálculo de prioridades. Todos los procesos en linux corren con determinada prioridad, un número entero, que puede verse en la salida de un comando top o htop.

htop

La tercer columna, etiquetada como PRI(ority) hace referencia a esta prioridad real del proceso dentro del sistema.

Ese 20 hace referencia a una prioridad media por defecto. Las prioridades de procesos de usuario se numeran desde 0 a 39. Mientras menor es el número, más alta será la prioridad, por lo que una prioridad cercana a 0 indicará mayor prioridad, y el proceso que la posea tendrá más chances de ser planificado en el procesador, que uno que tenga una prioridad más baja, cercana al 39.

La columna NI(ce) hace referencia a una prioridad que debería tener, por lo general mapea con la prioridad PRI, que depende del estado y carga de procesamiento, pero que va desde -20 a +19, donde -20 es la mayor prioridad de proceso de usuario (equivalente a un PRI de 0) y +19 es la menor prioridad de usuario (equivalente a un PRI de 39), siendo el NI de 0 la prioridad media, equivalente a un PRI de 20.

En fin, cuando se crea un proceso, se le asigna una prioridad NI determinada, y con ella se calcula la prioridad PRI = 20+NI. Luego, con la ejecución del sistema, puede modificarse PRI para beneficiar o penalizar al proceso.

El tema de las prioridades merece un artículo completo, así que en breve estará disponible en el blog 🙂

RT=Real time?

Como nota adicional, no estamos considerando las prioridades de tiempo real que provee el núcleo (real time). El total de prioridades de Linux es de 140, desde la prioridad 0 hasta la prioridad 139. Las 40 que vemos en las herramientas como renice, nice o top/htop, son en realidad las prioridades que van desde 100 a 139, las prioridades de procesos de usuario.

Las prioridades reales desde la 0 a la 99 son prioridades de tiempo real, no podemos modificarlas con herramientas de usuario, y, por ejemplo, en top/htop las veremos como «RT».

htop rt  procesos en linux

Cambiando prioridades de procesos en linux

Si quisiéramos ejecutar una tarea determinada, por ejemplo, alguna tarea que consuma intensivamente al procesador, y quisiéramos hacerlo con una prioridad menor de lo habitual de modo que el sistema no se ralentice demasiado, y nos deje «espacio» para trabajar, podríamos ejecutarla utilizando el comando nice de esta forma:

nice -[+|-]nn comando

Donde nn es un número positivo o negativo de prioridad, y el comando es la tarea a ejecutar.

Veamos un ejemplo, vamos a ejecutar el comando «yes > /dev/null &» con una prioridad baja de +10:

nice -+10 yes > /dev/null &

Y veamos el cambio en la línea marcada en la salida de un htop:

htop yes

Ahora bien, si por casualidad necesitáramos elevar la prioridad del proceso, supongamos, a -5 (5 puntos encima de la normal), podremos hacer uso del comando «renice» y utilizando el PID del proceso, en nuestro caso, 17016, de esta forma:

renice -5 17016

Y la salida del htop nos mostrará el siguiente resultado:

htop renice procesos en linux

Prioridades en htop y top

En la interfaz de htop podremos presionar F7 o F8 para aumentar o reducir la prioridad de un proceso respectivamente (siempre que tengamos privilegios, principalmente para aumentarla). Esto se aplica directamente al proceso que tengamos seleccionado en la interfaz del htop.

En top deberemos presionar la tecla «r» (renice) para cambiar la prioridad de un proceso. El top nos pedirá el PID del proceso en cuestión, y luego el número de prioridad a setear.

Conclusiones

Hemos aprendido hoy algo sobre la estructura jerárquica de procesos en Linux, sus estados de ejecución básicos, y sobre el manejo de prioridades utilizando herramientas de línea de comandos.

En próximos artículos hablaremos específicamente sobre el estado de ejecución de los procesos, procesos zombies, y algunas referencias a comunicación entre procesos (IPC) usando POSIX.1.

Hasta la próxima!


¿Preguntas? ¿Comentarios?

Si tenés dudas, o querés dejarnos tus comentarios y consultas, sumate al grupo de Telegram de la comunidad JuncoTIC!
¡Te esperamos!


Diego Córdoba

- Ingeniero en Informática - Mg. Teleinformática - Tesis pendiente - Docente universitario - Investigador

3 comentarios

Dany Andersen · 5 febrero, 2014 a las 14:36

Artículo muy completo y claro. Hace apenas un año que uso GNU/Linux (especialmente Ubuntu rt o Lowlatency). Ya estoy viendo la practicidad del uso de Terminal. Podría decirse que soy uno de esos usuarios "noveles". Encontré este artículo buscando mejorar la prioridad de muse-streamer, y me fue muy útil. Les doy gracias por tomarse el tiempo de explicar y difundir el Software Libre.

Diego Cordoba · 5 febrero, 2014 a las 14:39

Muchas gracias Dany! Es una satisfacción que el artículo te haya sido de utilidad! Y por supuesto, siempre es un gusto poder compartir conocimiento libre! Saludos!

Los comentarios están cerrados.