Procesos en Linux: ps, top, htop, kill, señales y nice
Los procesos en Linux se revisan con ps aux (una instantánea), top y htop (lista actualizada con la carga). Para terminar un proceso se usa kill PID, que por defecto envía un SIGTERM cortés; kill -9 (SIGKILL) solo se usa si el proceso no responde. La prioridad se fija con nice al arrancar el programa y con renice en un proceso que ya se está ejecutando, en un rango de -20 a 19.
Cualquier programa en ejecución en Linux es un proceso con su propio número PID, un propietario, un estado y una prioridad. Los procesos se consultan con ps, top y htop, se terminan con kill, y su prioridad se cambia con nice y renice. A continuación veremos cómo leer la salida de estos comandos, qué señal enviar en cada caso y por qué kill -9 no debería ser el primer recurso.
Qué es un proceso y su PID
Un proceso es un programa en ejecución: código, memoria, archivos abiertos y un conjunto de atributos. El núcleo asigna a cada proceso un identificador único, el PID, y guarda también el PPID, el número de su padre, que lo lanzó. El primer proceso del sistema, con PID 1, suele ser systemd, y es el «antepasado» de todos los demás.
Un proceso nuevo aparece en dos pasos. Primero, el padre llama a fork() y obtiene una copia de sí mismo; después, la copia llama a execve() y sustituye su código por el del nuevo programa. Cuando escribe ls en la terminal, bash hace exactamente esto y espera a que el hijo termine mediante wait().
$ echo $$ # PID del shell actual
4182
$ ps -o pid,ppid,cmd -p $$
PID PPID CMD
4182 4170 -bash
Cómo ver los procesos con ps
ps hace una instantánea: muestra los procesos exactamente en el momento en que se ejecuta y termina. Sin argumentos muestra solo los procesos de la terminal actual, así que en la práctica casi siempre se usa una de dos variantes.
$ ps aux | head -5
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 168540 12780 ? Ss 09:12 0:03 /sbin/init
root 2 0.0 0.0 0 0 ? S 09:12 0:00 [kthreadd]
www-data 1532 1.2 2.1 412308 86420 ? S 09:15 1:47 php-fpm: pool www
postgres 1610 0.4 3.8 221004 154312 ? Ss 09:15 0:31 postgres: checkpointer
Aquí a son los procesos de todos los usuarios, u es el formato detallado con el propietario, y x incluye los procesos sin terminal (demonios). La sintaxis alternativa al estilo System V es ps -ef: muestra el PPID, útil para saber quién lanzó a quién.
| Columna | Significado |
|---|---|
PID | identificador del proceso |
%CPU, %MEM | porcentaje del procesador y de la memoria física |
VSZ | memoria virtual en KB (incluye lo que no está cargado en RAM) |
RSS | memoria física realmente ocupada, en KB |
STAT | estado del proceso (R, S, D, Z, T) y banderas |
TIME | tiempo total de CPU consumido, no el tiempo de ejecución |
Trucos útiles con ps
# los 10 que más memoria usan
ps aux --sort=-%mem | head -11
# los 10 que más CPU usan
ps aux --sort=-%cpu | head -11
# columnas a medida
ps -eo pid,ppid,user,ni,stat,etime,cmd
# árbol de procesos
ps -ef --forest
pstree -p
# buscar el PID por nombre
pgrep -a nginx
pidof nginx
Un error clásico es buscar un proceso con ps aux | grep nginx y ver en la salida el propio grep. Use pgrep o el truco grep [n]ginx, que no coincide con su propia línea de comandos.
Estados de los procesos: R, S, D, Z, T
La letra de la columna STAT no es un detalle: es el estado real del proceso. De ella depende cómo interpretar la carga y si kill servirá de algo.
| Código | Estado | Qué significa en la práctica |
|---|---|---|
R | Running | se está ejecutando o espera turno en la CPU |
S | Interruptible sleep | espera un evento (red, entrada, temporizador); es el estado normal de la mayoría de procesos |
D | Uninterruptible sleep | espera una operación de E/S dentro del núcleo; no admite señales |
Z | Zombie | ha terminado, pero su padre no ha recogido el código de salida |
T | Stopped | detenido por SIGSTOP o por Ctrl+Z |
También son útiles los caracteres que siguen a la letra: s indica líder de sesión, + proceso en primer plano de la terminal, < prioridad elevada, N prioridad reducida y l proceso multihilo.
Proceso en estado D
Un proceso en D está dentro de una llamada al sistema y espera, por ejemplo, la respuesta de un disco o de un NFS bloqueado. No le llega ninguna señal, ni siquiera SIGKILL. Por eso kill -9 no sirve de nada aquí: hay que buscar la causa de la espera, revisando iostat, dmesg y el estado del almacenamiento de red.
Procesos zombi
Un zombi ya está muerto: no consume CPU ni memoria, solo ocupa una entrada en la tabla de procesos. No se puede matar, porque ya ha terminado. Desaparece cuando el padre llama a wait() o cuando el propio padre termina y el PID 1 lo adopta.
# buscar zombis y sus padres
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/'
Un zombi aislado es inofensivo. Si son cientos y su número crece, el fallo está en el programa padre: hay que corregirlo o reiniciarlo.
top: procesos y carga en tiempo real
top muestra la misma lista, pero la actualiza cada pocos segundos y añade un resumen del sistema. Es lo primero que se ejecuta cuando «el servidor va lento».
top - 14:21:07 up 12 days, 3:02, 2 users, load average: 1.84, 1.20, 0.95
Tasks: 213 total, 2 running, 211 sleeping, 0 stopped, 0 zombie
%Cpu(s): 23.1 us, 4.2 sy, 0.0 ni, 70.3 id, 1.9 wa, 0.0 hi, 0.5 si, 0.0 st
MiB Mem : 7821.4 total, 412.6 free, 3105.8 used, 4303.0 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 4398.2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1532 www-data 20 0 412308 86420 14212 R 38.2 1.1 1:47.31 php-fpm
1610 postgres 20 0 221004 154312 148900 S 6.0 1.9 0:31.08 postgres
En la línea %Cpu(s) lo más importante es: us, código de usuario; sy, núcleo; id, inactivo; wa, espera de disco. Un valor alto de wa con el procesador libre indica con seguridad que el cuello de botella está en la E/S.
Teclas de top
| Tecla | Acción |
|---|---|
P / M | ordenar por CPU / por memoria |
1 | mostrar cada núcleo por separado |
c | línea de comandos completa |
u | filtrar por usuario |
k | enviar una señal a un proceso |
r | cambiar el nice de un proceso |
H | mostrar los hilos |
q | salir |
Para scripts y logs es útil el modo por lotes: top -b -n 1 | head -20 muestra una sola instantánea sin interactividad. Para seguir un proceso concreto, use top -p 1532.
Load average: es una cola, no un porcentaje
Los tres números de load average son la longitud media de la cola en los últimos 1, 5 y 15 minutos. En Linux a esa cola llegan los procesos en estado R y D, pero no los que duermen en S. Para interpretarla, compárela con el número de núcleos (nproc): en 4 núcleos, un valor de 4 significa carga completa, y 12 indica una cola tres veces mayor que la capacidad.
Si el load average es alto pero el procesador está inactivo, busque procesos en D: ps -eo stat,pid,cmd | grep '^D'. Casi siempre se trata de un disco lento o de un almacenamiento de red.
htop: un top más cómodo
htop muestra lo mismo, pero con indicadores de color por núcleo, desplazamiento, soporte de ratón y árbol de procesos. Normalmente hay que instalarlo: sudo apt install htop o sudo dnf install htop.
F3o/— buscar un proceso por nombre;F4— filtro que deja solo las coincidencias;F5ot— árbol «padre — hijos»;F6— elegir la columna de ordenación;F7/F8— bajar o subir el nice;F9— menú de señales para el proceso seleccionado;Espacio— marcar varios procesos para una acción conjunta.
En servidores donde no se puede instalar nada basta con top: todas las operaciones clave también están en él.
Cómo terminar un proceso: kill y las señales
El comando kill no «mata» directamente: envía una señal al proceso. Lo que ocurra después depende de la señal y de cómo el programa la gestione.
| Señal | Número | Uso |
|---|---|---|
SIGHUP | 1 | corte de la terminal; muchos demonios releen la configuración |
SIGINT | 2 | interrupción, igual que Ctrl+C |
SIGKILL | 9 | terminación forzada por el núcleo; no se puede capturar |
SIGTERM | 15 | petición de terminar ordenadamente; es la señal por defecto de kill |
SIGSTOP | 19 | pausar; no se puede capturar |
SIGCONT | 18 | reanudar un proceso pausado |
SIGTSTP | 20 | pausa desde la terminal, Ctrl+Z |
Los números corresponden a x86 y ARM; la lista completa la muestra kill -l. Es más seguro indicar la señal por su nombre que por su número.
kill 1532 # SIGTERM
kill -TERM 1532 # lo mismo, explícito
kill -HUP $(pidof nginx) # releer la configuración
kill -STOP 1532; kill -CONT 1532
kill -0 1532 && echo "el proceso sigue vivo"
La señal 0 no envía nada: solo comprueba si el proceso existe y si usted tiene permiso para enviarle señales, lo cual resulta útil en scripts.
Por qué no empezar con kill -9
SIGTERM da al programa la oportunidad de cerrar archivos, volcar los búferes, borrar los archivos de bloqueo y terminar las transacciones de forma correcta. SIGKILL corta todo de golpe: los datos a medio escribir se pierden, quedan archivos temporales y una base de datos puede entrar en recuperación al arrancar de nuevo.
La secuencia correcta es:
- Enviar
kill PID(SIGTERM). - Esperar de 5 a 30 segundos, comprobando con
kill -0 PID. - Solo si el proceso sigue vivo y no está en estado
D, usarkill -9 PID.
Para los servicios gestionados por systemd lo mejor es no tocar el PID a mano: systemctl stop envía SIGTERM, espera el tiempo de espera y, si hace falta, envía SIGKILL.
pkill y killall: por nombre
pkill -f "python worker.py" # por la línea de comandos completa
pkill -u alice # todos los procesos del usuario
killall -TERM node # todos los procesos llamados node
pgrep -l -f worker # primero compruebe qué coincidirá con el patrón
Antes de un pkill masivo ejecute siempre pgrep con el mismo patrón: -f coincide con cualquier parte de la línea de comandos y puede alcanzar procesos que no quería.
Las señales solo se pueden enviar a los procesos propios; para los ajenos hace falta sudo. El error Operation not permitted significa precisamente esto.
Prioridad de los procesos: nice y renice
El valor nice indica al planificador cuánto debe ceder el procesador. El rango va de -20 (prioridad más alta) a 19 (cede a todos), y por defecto es 0. En top aparece en la columna NI; PR es la prioridad interna derivada.
# lanzar una tarea pesada con prioridad baja
nice -n 10 tar czf backup.tar.gz /var/www
# bajar la prioridad de un proceso en ejecución
renice -n 15 -p 1532
# subir la prioridad (solo root)
sudo renice -n -5 -p 1610
# todos los procesos de un usuario
sudo renice -n 10 -u alice
Un usuario normal solo puede bajar la prioridad de sus propios procesos; los valores negativos están reservados para root. Hay que tener en cuenta que nice solo afecta a la CPU. Si una tarea satura el sistema a través del disco, use ionice -c3 comando: la clase idle recibe el disco solo cuando nadie más lo necesita.
Procesos en segundo plano y trabajos del shell
Un comando se puede lanzar en segundo plano añadiendo &, o pausarse con Ctrl+Z. El shell lleva una lista de trabajos que se gestiona con comandos integrados.
$ tarea_larga &
[1] 5120
$ jobs
[1]+ Running tarea_larga &
$ fg %1 # traer al primer plano
^Z # pausar (SIGTSTP)
$ bg %1 # seguir en segundo plano
Al cerrar la terminal, el shell envía SIGHUP a sus trabajos y estos terminan. Para que un proceso sobreviva a la salida, láncelo con nohup comando &, desvincúlelo con disown o use tmux. Para un trabajo permanente, lo correcto es crear un servicio de systemd.
Escenarios típicos de diagnóstico
Quién consume la CPU
top -o %CPU # o la tecla P dentro de top
ps -eo pid,user,%cpu,etime,cmd --sort=-%cpu | head
Si un proceso consume CPU sin necesidad, primero bájele la prioridad con renice: es seguro y le da tiempo para investigar.
Quién ocupa un puerto
sudo ss -ltnp | grep :8080
sudo lsof -i :8080
La salida muestra el PID, y a partir de él, en /proc/PID/, puede encontrar el ejecutable (exe), el directorio de trabajo (cwd) y los argumentos (cmdline).
El proceso ha desaparecido de repente
Una causa frecuente es el OOM Killer, que termina procesos cuando falta memoria. Para comprobarlo: dmesg -T | grep -i oom o journalctl -k | grep -i "killed process".
Resumen
Para trabajar con procesos en Linux basta con un conjunto pequeño de comandos: ps aux para la instantánea, top y htop para la observación, kill con la señal adecuada para terminar, y nice/renice para las prioridades. Lea el estado del proceso antes de actuar: los zombis y los procesos en D no se curan con señales. Empiece siempre con SIGTERM y deje kill -9 para el último recurso. Los procesos, la memoria, el load average y las llamadas al sistema se explican con detalle en la práctica del curso de Linux.
Preguntas frecuentes
¿En qué se diferencia ps aux de ps -ef?
Son dos sintaxis del mismo comando: aux es el estilo BSD, con las columnas %CPU, %MEM y STAT; -ef es el estilo System V, con la columna PPID. En ambos casos aparecen los mismos procesos, todos los del sistema.
¿Cómo saber cuántos procesos hay en el sistema?
Lo más sencillo es mirar la línea Tasks de top o ejecutar ps -e --no-headers | wc -l. El número de hilos lo muestra ps -eLf --no-headers | wc -l.
¿Por qué un proceso no termina ni siquiera con kill -9?
O bien está en estado D esperando una operación de E/S dentro del núcleo, o bien es un zombi que ya ha terminado. En el primer caso busque el problema en el disco o en el almacenamiento de red; en el segundo, corrija o reinicie el proceso padre.
¿Qué pasa si se intenta terminar el proceso con PID 1?
El núcleo protege a init: las señales habituales, incluido SIGKILL de un usuario, no se le entregan si no las gestiona. Si init llegara a terminar, el sistema entraría en kernel panic.
¿Cómo limitar la memoria que puede usar un proceso?
Para un servicio de systemd, use MemoryMax= en su archivo de unidad; para un lanzamiento puntual, systemd-run --scope -p MemoryMax=500M comando. Esto funciona con cgroups y es más fiable que el antiguo ulimit -v.
Este tema se explica a fondo y con práctica en el curso «Linux: с нуля до уверенного администрирования».
Ir al curso