- Linux gestiona procesos e hilos ligeros (LWPs) de forma unificada, con límites configurables en /proc y factores como tamaño de pila y memoria que condicionan el máximo de hilos.
- Comandos como ps, top, htop y atop permiten listar y monitorizar procesos y LWPs, mientras que /proc y ps en modo hilos facilitan conocer el número de hilos por proceso.
- Herramientas como kill, pkill, nice, renice, strace, lsof, vmstat o iostat sirven para controlar, priorizar y depurar procesos, optimizando el rendimiento global del sistema.

Si administras servidores o trabajas a menudo con Linux, tarde o temprano vas a necesitar listar procesos, hilos ligeros (LWPs) y controlar su consumo de recursos. Saber qué se está ejecutando, cuántos recursos usa y cómo se organiza cada proceso es clave para detectar cuellos de botella, caídas de servicios o comportamientos raros en el sistema.
En las siguientes líneas vas a encontrar una guía muy completa en la que veremos qué son los procesos y LWPs, cómo listarlos, cómo ver sus límites y cómo monitorizarlos en tiempo real. Tomaremos como base los comandos clásicos (ps, top, htop…) y también técnicas algo más avanzadas con /proc, herramientas de diagnóstico y ajustes de prioridades, todo explicado en un español de España cercano y sin rodeos.
Procesos, hilos y LWPs en Linux: conceptos básicos
En Linux, cuando ejecutas un programa se crea un proceso que es la instancia de ese programa en memoria, junto con todos los recursos que necesita: código, datos, descriptores de archivo, pila, etc. Cada proceso recibe un identificador único llamado PID (Process ID), que es el número que luego usamos para supervisarlo o matarlo.
Además de los procesos “normales” o pesados, el kernel maneja los llamados hilos ligeros o LWPs (LightWeight Processes). Un LWP comparte con otros hilos del mismo proceso buena parte de los recursos (código, datos, ficheros abiertos, señales…), pero mantiene su propia pila y contexto de ejecución. Eso hace que el cambio de contexto entre hilos sea mucho más barato que entre procesos independientes.
Algo curioso de Linux es que, internamente, no diferencia de forma estricta entre proceso e hilo: ambos se gestionan como tareas del kernel, y un hilo es básicamente un “proceso” que comparte recursos con otros. No existen estructuras especiales de hilo a nivel de kernel como en otros sistemas operativos, aunque en la práctica podemos usar LWPs para obtener paralelismo real en sistemas multinúcleo.
Ese paralelismo se consigue repartiendo el trabajo de una aplicación en varios hilos de ejecución. Cada LWP puede ejecutarse en un núcleo distinto del procesador, de modo que el programa aprovecha todos los cores disponibles. Como el coste de crear y conmutar LWPs es bajo, Linux es muy eficiente ejecutando cantidades grandes de hilos, siempre que respetemos los límites del sistema.
Límites de procesos e hilos en Linux
Como en cualquier sistema operativo, hay un número máximo de tareas que el kernel puede manejar simultáneamente. En Linux, estos límites de procesos e hilos se exponen como parámetros del kernel dentro del pseudo-sistema de archivos /proc, en la ruta /proc/sys/kernel/.
El límite global de hilos que puede soportar el kernel se guarda en el fichero /proc/sys/kernel/threads-max. Si consultas el contenido de ese archivo con cat o sysctl, obtendrás el número máximo de LWPs que el sistema es capaz de crear antes de negarse a lanzar más tareas.
Ese valor suele ser bastante alto en servidores modernos con varios núcleos y mucha RAM, mientras que en equipos modestos o máquinas virtuales pequeñas puedes encontrarte números más bajos. Si se alcanza ese tope y ningún proceso termina, el kernel no podrá crear nuevos procesos ni hilos, lo que puede provocar errores al lanzar servicios o comandos.
Existe otro límite importante en /proc/sys/kernel/pid_max, que indica el máximo identificador de proceso que se puede asignar. Este valor también actúa en la práctica como límite para el número de procesos (y por extensión, hilos) que pueden coexistir, ya que Linux trata a ambos de forma unificada. Cuando el contador de PIDs llega a ese máximo, vuelve a empezar desde abajo, y es normal ver PIDs “repetidos” con el tiempo, pero pertenecientes a procesos completamente distintos.
Cálculo del número máximo de hilos y ajuste de la pila
El número real de LWPs que puedes tener en un sistema Linux no depende solo de esos parámetros del kernel, sino también de la memoria virtual disponible y del tamaño de la pila de cada hilo. Una fórmula aproximada muy usada es:
máximo de hilos ≈ memoria virtual / (tamaño de pila × 1024 × 1024)
En esa expresión, el tamaño de pila por hilo suele consultarse con el comando ulimit -s. Este valor indica cuántos kilobytes de memoria se reservan para la pila de cada LWP que se crea. A mayor tamaño de pila, mayor seguridad ante desbordamientos, pero también menos hilos simultáneos podrás tener por la misma cantidad de memoria.
Si necesitas levantar una aplicación con miles o decenas de miles de hilos, puede ser interesante reducir el tamaño de la pila por hilo usando de nuevo ulimit (por ejemplo en scripts de arranque o servicios de sistema), siempre y cuando el código de la aplicación no requiera pilas enormes.
En resumen, el número de LWPs en Linux está limitado por: parámetros del kernel (threads-max, pid_max), tamaño de la pila por hilo y memoria total disponible. Ajustando esos factores con cuidado puedes escalar la cantidad de hilos concurrentes sin comprometer la estabilidad del sistema.
Comandos básicos para listar procesos y LWPs
Para empezar a trabajar con procesos e hilos en Linux, la herramienta clásica es el comando ps, que muestra el estado de los procesos en una instantánea puntual (no es en tiempo real). A diferencia de un monitor gráfico, su salida es estática: si quieres información actualizada, simplemente vuelves a lanzarlo.
Con ps sin opciones solo verás los procesos ligados a la shell actual. Para obtener todos los procesos del sistema, incluyendo los que no tienen terminal asociada, lo habitual es usar:
ps aux
En esa salida verás, entre otros datos, el usuario propietario, el PID, el porcentaje de CPU y RAM usados, el tiempo de ejecución y el comando con el que se lanzó cada proceso. Es mucha información, pero resulta imprescindible para localizar tareas que se están comiendo la máquina.
Algunas combinaciones útiles de ps para tener más control sobre lo que aparece son:
ps -eops -A: listan todos los procesos activos en formato genérico UNIX.ps -u nombre_usuario: muestra únicamente los procesos de un usuario concreto.ps -axjf: enseña la salida en formato jerárquico, anidando procesos hijo bajo sus padres.ps -C nombre_proceso: filtra por nombre de comando e incluye los procesos hijo asociados.
Otra opción habitual es usar ps aux | grep patrón para quedarte solo con los procesos que contengan ese texto, por ejemplo un demonio web, un motor de base de datos o un script concreto. Es una forma muy cómoda de localizar de un vistazo lo que buscas sin perderte en páginas y páginas de resultados.
Monitoreo en tiempo real con top y htop
Cuando necesitas ver cómo cambian los procesos en tiempo real, el comando estrella es top, que muestra un monitor dinámico de la actividad del sistema. A diferencia de ps, la salida se actualiza continuamente, mostrando el uso de CPU, memoria, carga media, número de tareas activas y un listado ordenado de procesos.
Al ejecutar simplemente top, verás los procesos ordenados por uso de CPU. Puedes reordenar por otros campos, filtrar, matar procesos o cambiar prioridades pulsando distintas teclas dentro de la propia interfaz (las combinaciones pueden variar ligeramente según la versión, pero suelen estar indicadas en la parte inferior).
Una forma típica de enfocarse en los procesos más pesados es usar una orden como:
top -o %CPU
Así colocas en la parte superior los procesos que más CPU están consumiendo, lo que es muy útil cuando algo ha empezado a disparar el uso del procesador y quieres encontrar al culpable rápidamente.
Si prefieres algo más visual, puedes instalar htop, una versión mejorada de top con interfaz interactiva, barras de color y navegación mediante teclado y ratón. En muchas distros tendrás que instalarlo primero con el gestor de paquetes, por ejemplo:
sudo apt-get install htop
Una vez instalado, ejecutas htop y tendrás una vista en colores de la carga por núcleo, memoria, swap, y una tabla de procesos en la que puedes desplazarte vertical y horizontalmente, filtrar por usuario, cambiar prioridades o matar procesos sin teclear el PID a mano.
Monitorización de recursos con atop
Para análisis de rendimiento más profundos, especialmente en servidores, existe la herramienta atop, que registra y muestra la actividad de todos los procesos con gran nivel de detalle. Es una utilidad de pantalla completa en modo texto que se centra en la evolución de la carga y el uso de recursos a lo largo del tiempo.
Cuando lanzas atop, verás estadísticas de CPU, memoria, swap, discos y red que se refrescan típicamente cada 10 segundos. Además, puede permanecer activo en segundo plano durante días, guardando historiales que luego puedes revisar para analizar un problema que ocurrió en el pasado.
Entre sus ventajas destacan la capacidad de agrupar consumo por usuario o por nombre de proceso, resaltar en color rojo los recursos críticos que van justos, mostrar procesos que ya han terminado pero aún tienen relevancia en el registro y supervisar hilos internos (LWPs) dentro de cada proceso.
En muchas distribuciones se instala con paquetes específicos; por ejemplo:
sudo apt install atop
sudo dnf install atop
Tras la instalación, basta con ejecutar atop para empezar a ver a nivel de proceso el consumo de CPU, memoria, disco y red, y así poder detectar con bastante precisión qué componente está saturando el sistema.
Cómo ver el número de hilos (LWPs) por proceso
Si lo que te interesa es saber cuántos hilos ligeros tiene un proceso concreto, Linux ofrece varios caminos para obtener esa información. El primero pasa por inspeccionar el pseudo-sistema de archivos /proc, donde el kernel expone datos internos de cada tarea.
Dentro de /proc/<PID>/ encontrarás el fichero status, que incluye el campo Threads. Leyendo ese archivo, puedes ver rápidamente cuántos LWPs ha creado el proceso con ese PID en particular, junto con otros muchos detalles como el estado, el consumo de memoria o las capacidades.
Otra forma usando /proc es mirar el contenido del directorio /proc/<PID>/task/. En esta ruta, el kernel crea un subdirectorio por cada hilo perteneciente al proceso. De modo que el conteo de directorios dentro de task coincide con el número de hilos. Puedes usar ls combinado con wc para hacer el recuento de forma automática.
Además del enfoque con /proc, el propio comando ps puede devolver información a nivel de hilo. Usando la opción -H entras en “modo hilos”, y con -p filtras por un PID concreto. Si añades -h evitas cabeceras, lo que facilita canalizar la salida hacia wc y obtener el número de líneas, es decir, el número de LWPs listados para ese proceso.
En todos estos métodos, si los aplicas sobre el mismo PID, el recuento de hilos debe coincidir: el campo Threads de status, el número de subdirectorios en task y las líneas de salida de ps en modo hilos deberían dar la misma cifra, salvo ligeras variaciones si el proceso está creando o destruyendo hilos justo en ese instante.
Filtrado y búsqueda de procesos con pgrep y grep
Cuando hay cientos o miles de procesos en la máquina, encontrar el que te interesa a golpe de scroll es una pérdida de tiempo. Para estas situaciones viene muy bien pgrep, que busca procesos por nombre o patrón y devuelve directamente los PIDs que coinciden.
Con un simple pgrep apache obtendrás en pantalla los identificadores de todos los procesos cuyo nombre incluye ese texto. Y si necesitas afinar más, puedes combinar pgrep con filtros por usuario, por ejemplo con la opción -u para limitar la búsqueda a los procesos de una cuenta concreta.
Otra táctica muy usada es apoyarse en grep para filtrar la salida de ps. Un comando típico podría ser ps aux | grep apache, que te mostrará solo las líneas de procesos que contienen la palabra “apache”, junto con sus PIDs, recursos y comandos completos.
Ten en cuenta que este tipo de tuberías añade procesos añadidos (como el propio grep o wc) a la lista, por lo que cuando haces cosas como ps r | wc -l el contador se incrementa por la fila de cabecera y por los procesos que forman parte del propio pipeline. Es importante interpretar bien estos resultados para no llevarse sustos con el número total de tareas.
En general, dominar ps + grep, pgrep y las opciones de filtrado te permite centrarte en lo que te interesa sin verte inundado por procesos del sistema que, la mayoría de las veces, puedes ignorar en un primer análisis.
Control y finalización de procesos
Listar y monitorizar procesos está genial, pero muchas veces lo que necesitas es terminar tareas problemáticas o controlar su estado para liberar recursos o recuperar la estabilidad del sistema. Linux ofrece varias herramientas muy directas para esto.
La más conocida es kill, que envía señales a procesos identificados por su PID. Si no especificas ninguna señal, se manda una SIGTERM que pide al proceso que termine de forma ordenada. Si se resiste, puedes recurrir a la señal SIGKILL (opción -9), que obliga a terminar el proceso inmediatamente sin darle opción a limpiar recursos.
Cuando no quieres ir recogiendo PIDs uno a uno, tienes pkill y killall, que operan por nombre. Con pkill firefox matarás todos los procesos cuyo nombre coincida con “firefox” para tu usuario, mientras que killall tiende a ser más agresivo y puede afectar a todas las instancias del programa en el sistema, incluso de otros usuarios, dependiendo de permisos.
También es muy útil entender cómo funcionan fg y bg para jugar con procesos en primer y segundo plano. Al suspender una tarea con Ctrl+Z y luego usar bg, la envías al background para que siga ejecutándose mientras recuperas la terminal. Si luego necesitas volver a interactuar con ella, fg la trae de vuelta al primer plano.
Por último, cuando quieres ejecutar algo que siga corriendo incluso tras cerrar la sesión, puedes combinar nohup con el envío al segundo plano, por ejemplo nohup script.sh &. Así el proceso no se abortará aunque cierres la terminal o se corte la conexión SSH, algo muy útil en tareas de larga duración. Si prefieres programarlo en el tiempo, consulta cómo programar tareas con cron y at.
Ajuste de prioridades con nice y renice
En sistemas multiusuario o con muchas tareas concurrentes, no basta con saber cuántos procesos o LWPs hay, también es importante decidir a qué procesos se les da preferencia en el uso de CPU. Ahí entran en juego los comandos nice y renice.
Cuando arrancas un proceso con nice -n valor comando estás fijando su prioridad relativa. El rango típico va de -20 (mayor prioridad) a 19 (menor prioridad), siendo 0 el valor por defecto. Un valor de nice más alto significa que el proceso será “más educado” y cederá CPU a otros cuando compita por recursos.
Por ejemplo, si tienes un script pesado que no urge pero quieres que corra de fondo sin estorbar, puedes lanzarlo con nice -n 10 ./script.sh, lo que le asigna una prioridad baja para que no acapare el procesador mientras otros procesos interactivos están trabajando.
Si en lugar de ajustar la prioridad al inicio necesitas modificar la prioridad de un proceso que ya está en marcha, usas renice. Con algo como renice -n 5 -p PID cambias el valor nice del proceso con ese PID, adaptándolo a las necesidades actuales (subiendo o bajando su prioridad).
Gestionar correctamente las prioridades con nice y renice ayuda a evitar que un único proceso o conjunto de hilos se lleve por delante la capacidad de respuesta del sistema, especialmente en servidores compartidos o entornos de producción con muchas cargas simultáneas.
Herramientas avanzadas para depurar y analizar procesos
Cuando un proceso o uno de sus LWPs se comporta de manera extraña, se bloquea o parece colgar el sistema, a menudo toca sacar herramientas de diagnóstico más avanzadas. Una de las más potentes es strace, que permite seguir en tiempo real las llamadas al sistema que hace un proceso. Para fallos más profundos del kernel existe una guía sobre usar crash y kdump.
Con un comando como strace -p PID puedes engancharte a un proceso ya en ejecución y ver qué syscalls realiza (lecturas de ficheros, escrituras, operaciones de red, señales, etc.). Esto es especialmente útil para averiguar por qué un proceso se queda esperando “algo”: quizá esté bloqueado intentando abrir un archivo que no existe, esperando en un socket, o atascado con permisos insuficientes.
Otro clásico del diagnóstico es lsof (List Open Files), que muestra los archivos abiertos por cada proceso, incluyendo ficheros de disco, sockets de red, dispositivos y más. Es muy práctico para detectar qué proceso está ocupando un puerto concreto, qué servicio mantiene un archivo bloqueado o qué tareas están leyendo cierto log.
Complementando a lsof, fuser te indica qué procesos utilizan un archivo o un puerto concreto. Por ejemplo, con una orden sobre un puerto TCP puedes encontrar enseguida qué demonio está escuchando en ese número y actuar en consecuencia, ya sea reconfigurándolo o deteniéndolo.
Para ir un paso más allá en el análisis de rendimiento, cuentas con pidstat, que ofrece estadísticas detalladas de CPU, memoria y E/S por proceso, y con watch, que permite ejecutar periódicamente comandos como ps -e o netstat para observar en pantalla cómo evolucionan los procesos o las conexiones con el tiempo.
Gestión de servicios y estado general del sistema
Muchos procesos importantes en Linux son en realidad servicios o daemons que se ejecutan en segundo plano, como servidores web, bases de datos o planificadores de tareas. En sistemas modernos con systemd, la herramienta central para manejar estos servicios es systemctl.
Con systemctl start nombre_servicio puedes arrancar un servicio, mientras que systemctl stop, restart y status te permiten detenerlo, reiniciarlo o ver su estado actual. También puedes habilitar o deshabilitar su arranque automático al iniciar el sistema, lo que impacta directamente en qué procesos aparecen listados tras un reboot.
En distribuciones más antiguas o configuraciones que todavía usan SysVinit, es frecuente encontrar el comando service para gestionar servicios. Aunque en muchos casos se ha visto desplazado por systemd, sigue siendo útil como capa de compatibilidad para iniciar, parar o reiniciar demonios concretos.
Más allá de los servicios, conviene tener una visión global del estado del sistema. El comando uptime muestra cuánto tiempo lleva encendida la máquina, cuántos usuarios hay conectados y la carga media reciente, lo que da una idea rápida de si el sistema está cómodo o saturado.
Para un análisis más fino del rendimiento, vmstat ofrece estadísticas de CPU, memoria, procesos y swap, mientras que iostat se centra en la E/S de disco, mostrando lecturas, escrituras y tiempos de respuesta de los dispositivos de almacenamiento. Estas herramientas son oro para detectar si los problemas vienen de CPU, RAM, disco o una combinación de todo.
Combinando todo lo anterior —listado de procesos y LWPs con ps y /proc, monitorización en tiempo real con top, htop o atop, filtros con pgrep, control con kill y ajustes con nice, junto con utilidades de diagnóstico como strace y lsof— es posible entender y controlar de forma muy precisa qué está ocurriendo en un sistema Linux en cualquier momento, identificar procesos e hilos problemáticos y mantener el rendimiento a raya incluso en entornos exigentes.
Redactor apasionado del mundo de los bytes y la tecnología en general. Me encanta compartir mis conocimientos a través de la escritura, y eso es lo que haré en este blog, mostrarte todo lo más interesante sobre gadgets, software, hardware, tendencias tecnológicas, y más. Mi objetivo es ayudarte a navegar por el mundo digital de forma sencilla y entretenida.