1. Los mismos mecanismos, otras prioridades
Los cinco bloques anteriores describieron una maquinaria: dos modos de ejecución, llamadas al sistema, interrupciones, un temporizador, un cambio de contexto. Esa maquinaria es prácticamente la misma en todos los sistemas operativos actuales. Lo que cambia de uno a otro son las decisiones que se toman con ella.
En el tema 19 encontramos un primer ejemplo: la duración del turno de CPU. Turnos cortos dan respuestas rápidas y desperdician tiempo en cambios; turnos largos aprovechan mejor el procesador y hacen esperar. No hay un valor correcto. Hay un valor adecuado para cada uso, y lo mismo ocurre con casi todas las decisiones de diseño.
Un sistema operativo no puede ser óptimo en todo, porque los objetivos se oponen entre sí:
| Objetivo | Significa | Se opone a |
|---|---|---|
| Rendimiento total | Completar la mayor cantidad de trabajo por hora. | La rapidez de respuesta: interrumpir menos rinde más. |
| Tiempo de respuesta | Reaccionar enseguida a cada acción del usuario. | El rendimiento total. |
| Cumplimiento de plazos | Garantizar que cierta tarea se ejecute antes de un límite. | El rendimiento y la equidad: hay que reservar capacidad. |
| Equidad | Que todos los usuarios y programas reciban su parte. | Los plazos: lo urgente debe pasar por delante. |
| Consumo de energía | Que la batería dure. | El rendimiento y la rapidez. |
| Tamaño | Caber en poca memoria. | La cantidad de funciones. |
| Aislamiento | Que un programa defectuoso o malicioso no afecte al resto. | El rendimiento y el tamaño: cada barrera cuesta. |
Cada tipo de sistema operativo es una elección dentro de esta tabla: qué fila se pone primero y cuáles se sacrifican. Con ese criterio recorremos los principales. Varios nacieron en épocas que repasamos en el tema 3; aquí interesa lo que cada uno optimiza y dónde sigue vivo.
2. Cuatro maneras de clasificar
Antes de los tipos, conviene despejar unas clasificaciones más simples, que se cruzan con ellos y que aparecen en cualquier texto sobre la materia:
| Criterio | Categorías | Ejemplos |
|---|---|---|
| Cantidad de usuarios | Monousuario: no distingue quién lo usa. Multiusuario: cuentas, dueños y permisos. | MS-DOS era monousuario. Unix fue multiusuario desde el principio. |
| Cantidad de tareas | Monotarea: un programa por vez. Multitarea: varios, por turnos. | MS-DOS, monotarea. Todos los sistemas actuales de uso general, multitarea apropiativa. |
| Cantidad de procesadores | Monoprocesador o multiprocesador. | Hoy, hasta un teléfono tiene ocho núcleos. |
| Propósito | General: ejecuta cualquier programa. Específico: construido para una función. | Ubuntu frente al sistema de un cajero automático. |
Los tres primeros criterios distinguían mucho en 1985 y casi nada hoy: los sistemas vigentes son multiusuario, multitarea y multiprocesador. Un teléfono parece monousuario, pero por dentro usa las cuentas de usuario para otro fin, como veremos en la sección 9. El criterio que sigue separando de verdad es el cuarto, y los tipos que vienen son sus variantes.
3. Sistemas por lotes
Un sistema por lotes (batch) ejecuta trabajos que no requieren intervención humana mientras corren. Los trabajos se anotan en una cola, y el sistema los procesa cuando dispone de recursos. Su objetivo es el rendimiento total.
Fue la primera forma de sistema operativo, y nunca desapareció: se mudó. Donde nadie está esperando frente a una pantalla, lo razonable sigue siendo encolar el trabajo y optimizar el conjunto.
| Dónde | Qué se encola |
|---|---|
| Supercomputadores y clústeres de cálculo | Simulaciones que ocupan miles de procesadores durante horas o días. Un gestor de colas decide cuándo le toca a cada una. |
| Bancos y grandes empresas | La liquidación nocturna de cuentas, la facturación mensual. |
| Desarrollo de software | La compilación y las pruebas automáticas que se disparan con cada cambio. |
| Cualquier servidor | Copias de seguridad, rotación de registros, tareas programadas. |
Sus decisiones de diseño siguen del objetivo. Como nadie percibe los cambios de turno, conviene que los turnos sean largos, o directamente dejar que cada trabajo termine: menos cambios de contexto y mejor uso de las cachés. Lo que se mide no es cuánto tarda en reaccionar el sistema, sino cuántos trabajos completa por día y cuánto pasa entre que uno se encola y termina.
En un Linux de uso general, el modo por lotes existe como una opción. El comando at ejecuta un trabajo a una hora dada, y batch, cuando la carga del sistema baja de cierto nivel. Y hay una política de planificación llamada SCHED_BATCH, que le indica al kernel que un proceso no es interactivo y puede ser tratado con turnos más largos.
4. Sistemas interactivos
Un sistema interactivo, o de tiempo compartido, reparte el procesador en turnos breves entre muchos programas, de modo que cada usuario reciba respuesta inmediata. Su objetivo es el tiempo de respuesta, con equidad entre todos.
Es el tipo que usamos en todo el curso, y al que pertenecen Linux, Windows y macOS en una computadora personal. Sus rasgos ya nos son familiares:
- Multitarea apropiativa, con turnos de milisegundos.
- Preferencia por lo interactivo. El planificador favorece a los procesos que pasan casi todo el tiempo dormidos y despiertan por una tecla o un clic, frente a los que calculan sin parar. Así el editor responde aunque haya una compilación en marcha.
- Protección entre programas y entre usuarios, porque se supone que conviven programas que no se conocen ni confían entre sí.
- Propósito general: no sabe de antemano qué se va a ejecutar.
El origen multiusuario sigue a la vista. Aunque hoy cada persona tenga su equipo, un servidor de Linux atiende a muchas a la vez, exactamente como los sistemas de los años setenta:
$ who
diego tty2 2026-10-11 09:14 (tty2)
ana pts/3 2026-10-11 10:02 (192.168.1.37)
luis pts/4 2026-10-11 10:31 (192.168.1.52)
Tres personas, una sentada frente al equipo y dos conectadas por la red, cada una con la impresión de tener la máquina para sí. El precio de este diseño es que no promete nada con exactitud. Lo comprobamos en el tema 19: una pausa de un milisegundo dura «un poco más», y cuánto más depende de lo que estén haciendo los demás.
5. Experimento: inclinar el reparto
Un sistema interactivo reparte la CPU con equidad, pero permite matizarla. Todo proceso de Linux tiene un valor de cortesía, nice, entre −20 y 19. Cuanto más alto, más «cortés» es el proceso: cede más ante los otros. El valor normal es 0, y cualquier usuario puede aumentar el de sus propios procesos.
Lo probamos con bucle, el programa del tema 19 que solo calcula. Lanzamos dos copias sobre el mismo procesador, una con cortesía normal y otra con la máxima:
$ taskset -c 0 ./bucle & # cortesía 0, la normal
[1] 6120
$ taskset -c 0 nice -n 19 ./bucle & # cortesía 19, la máxima
[2] 6121
$ top -b -n 1 | grep -E 'PID|bucle'
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6120 diego 20 0 2680 1024 936 R 98.6 0.0 0:11.83 bucle
6121 diego 39 19 2680 1024 936 R 1.4 0.0 0:00.17 bucle
$ kill %1 %2
En el tema 19, dos copias iguales recibían la mitad cada una. Ahora el reparto es de 98,6 a 1,4. Dos observaciones:
- El proceso cortés no queda en cero. El planificador de Linux convierte la cortesía en un peso y reparte en proporción a los pesos; nadie queda sin turno. Si el otro proceso terminara, el cortés pasaría a recibir el 100 %.
- Es una preferencia, no una garantía. Dice quién recibe más, no cuándo ni en qué plazo.
Es la manera de hacer trabajo por lotes en un sistema interactivo: una copia de seguridad o una conversión de video lanzadas con nice -n 19 usan toda la CPU que sobre y se apartan en cuanto alguien la necesita. Reducir la cortesía por debajo de cero, para recibir más que los demás, requiere ser administrador.
6. Sistemas de tiempo real
El nombre induce a error. «Tiempo real» no quiere decir rápido.
Un sistema de tiempo real es aquel en que un resultado es correcto solo si se produce antes de un plazo determinado. Un cálculo acertado que llega tarde es un fallo. Su objetivo es cumplir los plazos, y la cualidad que se le exige es ser predecible.
La bolsa de aire de un automóvil debe inflarse en unas decenas de milisegundos desde el impacto. Si el sistema que la controla tarda normalmente dos milisegundos, pero una vez cada millón tarda doscientos porque en ese instante estaba ocupado en otra cosa, no sirve. Lo que importa no es el tiempo promedio, sino el peor caso, y que ese peor caso esté acotado y se conozca de antemano. Un sistema de tiempo real puede ser más lento en promedio que uno de uso general, y a menudo lo es.
Según la gravedad de incumplir un plazo, se distinguen dos categorías:
| Tiempo real estricto | Tiempo real flexible | |
|---|---|---|
| En inglés | Hard real-time | Soft real-time |
| Incumplir un plazo es | Una falla del sistema, con posibles daños | Una pérdida de calidad, tolerable si es ocasional |
| Se exige | Garantía demostrable del peor caso | Que los incumplimientos sean raros |
| Ejemplos | Frenos, bolsas de aire, marcapasos, control de vuelo, robots industriales | Reproducción de audio y video, videollamadas, videojuegos |
Para dar garantías, estos sistemas toman decisiones opuestas a las de un sistema interactivo:
| Aspecto | Sistema interactivo | Sistema de tiempo real |
|---|---|---|
| Planificación | Reparto equitativo; todos avanzan | Por prioridad estricta: la tarea más prioritaria que esté lista se ejecuta siempre, y las demás esperan lo que haga falta |
| Desalojo | Al terminar el turno | En el instante en que una tarea más prioritaria pasa a estar lista |
| Interrupciones deshabilitadas | Por tramos breves, sin límite formal | Por tramos con duración máxima conocida |
| Memoria | Se entrega al usarla, con fallos de página | Se reserva por adelantado: un fallo de página tiene duración impredecible |
| Equidad | Es un objetivo | No se busca: una tarea poco prioritaria puede no ejecutarse nunca |
La cuarta fila se relaciona con el tema 18. Entregar la memoria en el momento del primer acceso es eficiente, pero convierte un simple acceso a memoria en una operación de duración incierta. Un programa de tiempo real pide al kernel que le asigne toda su memoria de antemano y que no la mueva.
Los sistemas construidos para esto se llaman RTOS, de Real-Time Operating System: FreeRTOS, Zephyr, VxWorks, QNX. Son pequeños, y su código es lo bastante breve como para analizar el tiempo máximo de cada operación.
En 1997, la sonda Mars Pathfinder empezó a reiniciarse sola a los pocos días de posarse. La causa fue una inversión de prioridades. Una tarea de baja prioridad tenía tomado un recurso que necesitaba una de alta prioridad, que quedó esperando. Mientras tanto, una tarea de prioridad media, que no tenía nada que ver, desalojaba una y otra vez a la baja, y así le impedía terminar y soltar el recurso. La tarea más importante del sistema quedaba bloqueada, indirectamente, por una menos importante, hasta que un mecanismo de vigilancia reiniciaba la nave. Los ingenieros lo reprodujeron en tierra y lo corrigieron a distancia, activando una opción del sistema operativo por la cual quien tiene tomado el recurso hereda temporalmente la prioridad de quien lo espera.
Linux nació como sistema interactivo y fue adquiriendo capacidades de tiempo real. Tiene políticas de planificación por prioridad estricta, llamadas SCHED_FIFO y SCHED_RR, que pasan por delante de todos los procesos normales. Y tras veinte años de desarrollo aparte, las modificaciones conocidas como PREEMPT_RT, que permiten desalojar al propio kernel casi en cualquier punto, se incorporaron por completo al kernel oficial en 2024. Con ellas es adecuado para tiempo real flexible y para muchas aplicaciones industriales; en los casos más críticos se siguen usando sistemas diseñados solo para eso.
7. Experimento: medir la latencia
La diferencia entre promedio y peor caso se puede medir. El siguiente programa es una ampliación de siesta.c, del tema 19: pide dos mil pausas de un milisegundo y registra cuánto se demoró cada despertar respecto de lo pedido. Ese retraso se llama latencia.
#include <stdio.h>
#include <time.h>
#define VUELTAS 2000
int main(void)
{
struct timespec pausa = { 0, 1000 * 1000 }; /* 1 milisegundo */
struct timespec antes, despues;
long total = 0, peor = 0;
for (int i = 0; i < VUELTAS; i++) {
clock_gettime(CLOCK_MONOTONIC, &antes);
nanosleep(&pausa, NULL);
clock_gettime(CLOCK_MONOTONIC, &despues);
/* microsegundos transcurridos, menos los 1000 pedidos */
long retraso = (despues.tv_sec - antes.tv_sec) * 1000000L
+ (despues.tv_nsec - antes.tv_nsec) / 1000 - 1000;
total += retraso;
if (retraso > peor)
peor = retraso;
}
printf("Retraso promedio: %ld us\n", total / VUELTAS);
printf("Peor retraso: %ld us\n", peor);
return 0;
}
Lo ejecutamos en tres condiciones: con el equipo en reposo; con todos los procesadores ocupados por copias de bucle; y en esa misma situación, pero con una política de tiempo real. El comando chrt -f 50 lanza un programa con la política SCHED_FIFO y prioridad 50, y requiere sudo.
$ gcc -Wall -Wextra -g latencia.c -o latencia
$ ./latencia # equipo en reposo
Retraso promedio: 61 us
Peor retraso: 187 us
$ for i in $(seq $(nproc)); do ./bucle & done # ocupar todos los procesadores
$ ./latencia # con carga, política normal
Retraso promedio: 412 us
Peor retraso: 6120 us
$ sudo chrt -f 50 ./latencia # con carga, política de tiempo real
Retraso promedio: 9 us
Peor retraso: 48 us
$ kill $(jobs -p) # detener los bucles
| Condición | Promedio | Peor caso | Qué ocurre |
|---|---|---|---|
| En reposo | 61 µs | 187 µs | Al despertar hay un procesador libre. |
| Con carga, política normal | 412 µs | 6120 µs | Al despertar, el programa debe esperar a que el planificador le dé un turno entre los demás. |
Con carga, SCHED_FIFO | 9 µs | 48 µs | Al despertar, desaloja de inmediato a quien esté en la CPU. |
Los valores cambian mucho de un equipo a otro; la relación entre las tres filas, no. Con la política normal, el promedio empeora siete veces y el peor caso, más de treinta: algún despertar tuvo que esperar seis milisegundos. Para un reproductor de audio, eso es un chasquido audible. Con la política de tiempo real, el programa es indiferente a la carga, y su resultado es incluso mejor que en reposo, porque el kernel deja de agrupar sus despertares con los de otros procesos.
El experimento muestra también el costo. La política de tiempo real no hizo más rápido al equipo: decidió que este programa pasa siempre por delante. Los bucles perdieron ese tiempo.
chrt
Un proceso con política de tiempo real no cede la CPU a los procesos normales mientras tenga algo que hacer. Si entra en un bucle infinito, deja sin procesador a todo lo demás que debía correr en ese núcleo, incluida la terminal desde la que querrías detenerlo. Linux se reserva por precaución un 5 % del tiempo para los procesos normales, lo que evita el bloqueo total, pero el equipo queda casi inutilizable. latencia es inofensivo porque pasa casi todo el tiempo dormido.
8. Sistemas embebidos
Un sistema embebido es una computadora integrada en un aparato para cumplir una función específica. Su sistema operativo, si lo tiene, está construido a la medida de esa función y de un hardware limitado.
Son, por mucho, la mayoría de las computadoras que existen. Un automóvil actual tiene más de cien; una casa, decenas: el lavarropas, el horno de microondas, el control remoto, el termostato, el enrutador. No tienen teclado ni pantalla en el sentido habitual, y quien los usa no piensa en ellos como computadoras.
Sus condiciones de trabajo explican su diseño:
- Recursos mínimos. Un microcontrolador puede tener 32 KB de memoria y costar menos de un dólar. Cuando se fabrican millones de unidades, cada centavo cuenta.
- Consumo. Muchos funcionan años con una pila.
- Funcionamiento desatendido. Deben arrancar solos y recuperarse solos de cualquier fallo, sin nadie que pulse un botón.
- Función fija. Los programas que ejecutará se conocen al fabricarlo.
- Plazos. Casi siempre controlan algo físico, de modo que suelen ser a la vez sistemas de tiempo real.
Según los recursos disponibles, hay tres escalones:
| Sin sistema operativo | Con un RTOS | Con Linux embebido | |
|---|---|---|---|
| Memoria típica | De bytes a pocos KB | De decenas de KB a pocos MB | Desde unas decenas de MB |
| Estructura | Un único programa: un bucle que consulta las entradas y actúa | Varias tareas con prioridades, enlazadas con el kernel en una sola imagen | Kernel y procesos separados, como en una PC |
| Modos y protección de memoria | No | Por lo general, no | Sí |
| Arranque | Instantáneo | Milisegundos | Segundos |
| Ejemplos | Control remoto, termómetro | Dron, reloj deportivo, inyección de un motor | Enrutador, televisor, pantalla de un automóvil |
La tercera fila merece atención. Los microcontroladores no tienen unidad de gestión de memoria ni, en muchos casos, la distinción entre modos del tema 12. En un RTOS típico, el kernel y todas las tareas comparten un único espacio de direcciones, y una «llamada al sistema» es una llamada a función corriente. Es más rápido y más pequeño, y significa que un puntero equivocado en cualquier tarea puede corromper a las demás y al propio kernel. La protección que dimos por sentada en todo el curso es un lujo que requiere hardware.
En el escalón superior, lo que se instala es un Linux reducido a lo indispensable: un kernel compilado solo con los drivers de ese aparato y un espacio de usuario mínimo, a menudo basado en busybox, el ejecutable múltiple que encontramos en el initramfs del tema 21. Un enrutador doméstico es un Linux completo en 16 MB.
9. Sistemas móviles
Un teléfono tiene la potencia de una computadora personal y unas restricciones que una computadora personal no tiene. De ellas sale un tipo de sistema propio, representado por Android e iOS.
| Restricción | Respuesta del sistema |
|---|---|
| Funciona con batería | Todo el diseño gira en torno al consumo. El sistema decide cuándo puede ejecutarse una aplicación en segundo plano, agrupa sus despertares y apaga lo que no se usa. Los procesadores combinan núcleos rápidos y núcleos de bajo consumo, y el planificador elige según el trabajo. |
| Aplicaciones de miles de autores desconocidos | Cada aplicación está aislada de las demás, y solo accede a la cámara, los contactos o la ubicación si el usuario lo autoriza. |
| Memoria limitada, sin disco al que descargarla | Cuando falta memoria, el sistema finaliza las aplicaciones que no están a la vista. Deben poder reanudarse como si nada. |
| Interacción táctil | La respuesta al dedo tiene prioridad sobre todo lo demás: es tiempo real flexible. |
La tercera fila invierte una regla que parecía universal. En una computadora, el usuario decide cuándo empieza y cuándo termina un programa. En un teléfono lo decide el sistema: «cerrar» una aplicación es una sugerencia, y que siga abierta, una ilusión que el sistema mantiene mientras puede.
La segunda fila muestra un uso ingenioso de un mecanismo antiguo. Android está construido sobre el kernel de Linux, que es multiusuario. En lugar de usar las cuentas para distinguir personas, asigna a cada aplicación su propio usuario. La protección entre usuarios, que existe desde los años setenta, pasa a proteger los datos de una aplicación frente a las otras, sin escribir un mecanismo nuevo.
Como señalamos en el tema 10, de Linux Android toma solo el kernel. La biblioteca de C, el sistema de inicio y el entorno en que corren las aplicaciones son propios.
10. Servidores, virtualización y nube
Un sistema operativo de servidor no es otro kernel: es el mismo, orientado a otras prioridades. No tiene pantalla ni usuario delante; atiende a miles de clientes por la red, debe funcionar meses sin interrupción y busca aprovechar al máximo un hardware costoso. Vuelve a importar el rendimiento total, como en los sistemas por lotes, sin perder la capacidad de responder en un tiempo razonable.
Ese aprovechamiento llevó a una idea que hoy sostiene toda la nube: que una máquina física aloje a muchos clientes que no se conocen, cada uno convencido de tener un equipo propio. Hay dos técnicas, que aíslan en niveles distintos.
| Máquina virtual | Contenedor | |
|---|---|---|
| Qué simula | Una computadora completa | Un sistema operativo aparte |
| Kernel | Cada una el suyo; pueden ser sistemas distintos | Todos comparten el del anfitrión |
| Lo proporciona | Un hipervisor, que controla a los kernels como un kernel controla a los procesos | El propio kernel, que da a cada grupo de procesos su vista de los archivos, la red y los demás procesos |
| Arranque | Segundos o minutos: un arranque completo | Milisegundos: es lanzar un proceso |
| Memoria adicional | Cientos de MB por máquina | Casi ninguna |
| Aislamiento | Fuerte | Menor: un fallo del kernel compartido afecta a todos |
El hipervisor es el nivel de privilegio «por debajo del kernel» que mencionamos en el tema 12. El equipo físico se llama anfitrión, y cada máquina virtual, huésped. Si preparaste tu entorno con una máquina virtual o con WSL en el tema 4, estás usando esta técnica, y el sistema lo sabe:
$ systemd-detect-virt
oracle
| Respuesta | Significa |
|---|---|
none | Linux instalado directamente sobre el hardware. |
oracle, vmware, kvm, microsoft | Una máquina virtual sobre VirtualBox, VMware, KVM o Hyper-V. |
wsl | El subsistema de Windows para Linux. |
docker, podman, lxc | Un contenedor. |
La virtualización y los contenedores son el tema de un curso completo de esta ruta.
11. Sistemas distribuidos
Un sistema distribuido es un conjunto de computadoras independientes, conectadas por una red, que se presenta ante sus usuarios como un único sistema.
La ambición es llevar un paso más allá la abstracción del tema 2. Un sistema operativo oculta que hay varios procesadores y varios discos, y ofrece procesos y archivos. Un sistema distribuido oculta que hay varias máquinas: el usuario abre un archivo sin saber en cuál está guardado, y lanza un trabajo sin saber en cuál se ejecutará.
Hay que distinguir tres grados de integración:
| Sistema en red | Clúster | Sistema operativo distribuido | |
|---|---|---|---|
| El usuario percibe | Varias máquinas. Elige a cuál conectarse | Un servicio único, que sabe compuesto de muchas máquinas | Una sola máquina |
| Cada equipo ejecuta | Su propio sistema, independiente | Su propio sistema, más un software de coordinación | Una parte de un único sistema |
| Ejemplos | Cualquier Linux o Windows con conexión de red | Un supercomputador, Kubernetes, una base de datos repartida | Amoeba, Plan 9: sistemas de investigación |
La tercera columna fue un campo de investigación muy activo en los años ochenta y noventa, y no se impuso. Los sistemas operativos siguieron siendo de una sola máquina, y la distribución se construyó por encima, con programas y servicios: sistemas de archivos en red, gestores de clústeres, bases de datos repartidas. Es la segunda columna, y es como funciona hoy toda la nube. Un gestor como Kubernetes cumple, para un centro de datos, el papel que un kernel cumple para una máquina: decide en qué equipo se ejecuta cada cosa, reparte los recursos y reinicia lo que falla.
Lo que hace difíciles a estos sistemas son tres problemas que una máquina sola no tiene:
- Las fallas parciales. En una máquina, o funciona todo o no funciona nada. En un conjunto, una parte puede fallar mientras el resto sigue, y a veces no hay forma de distinguir una máquina caída de una red lenta.
- La ausencia de un reloj común. Cada máquina tiene el suyo, y nunca coinciden exactamente. Saber qué ocurrió antes y qué después deja de ser trivial.
- La demora de la comunicación. Un acceso a memoria tarda nanosegundos, y un mensaje por la red, entre mil y un millón de veces más. Es la escala del tema 7, con un escalón añadido.
12. Un kernel para casi todo
La clasificación podría sugerir que cada tipo requiere un sistema operativo distinto. La realidad actual es otra: casi todos los tipos tienen una versión basada en el mismo kernel.
| Tipo | Linux, en esa función |
|---|---|
| Por lotes | Los quinientos supercomputadores más potentes del mundo, sin excepción, desde 2017. |
| Interactivo | Las distribuciones de escritorio; ChromeOS. |
| Servidor y nube | La mayor parte de los servidores de Internet y de las máquinas virtuales de todos los proveedores. |
| Móvil | Android. |
| Embebido | Enrutadores, televisores, cámaras, sistemas de entretenimiento de automóviles y aviones. |
| Tiempo real | Con PREEMPT_RT, en control industrial, audio profesional y robótica. |
Solo queda fuera el extremo inferior: los microcontroladores sin unidad de gestión de memoria, que siguen siendo territorio de los RTOS.
Un mismo código fuente sirve para usos tan distintos porque es configurable en tres niveles:
- Al compilarlo. Miles de opciones deciden qué se incluye. Son las del archivo
configde/bootque vimos en el tema 11. El kernel de un enrutador se compila con una fracción de las que usa una distribución de escritorio. - Al arrancarlo y en marcha, con los parámetros del tema 21 y los ajustes de
/procy/sys. - En el espacio de usuario. Sobre un kernel casi idéntico, Ubuntu y Android construyen sistemas irreconocibles entre sí.
$ grep -E '^CONFIG_(PREEMPT_DYNAMIC|NR_CPUS|HZ)=' /boot/config-$(uname -r)
CONFIG_PREEMPT_DYNAMIC=y
CONFIG_NR_CPUS=8192
CONFIG_HZ=1000
$ uname -v
#45-Ubuntu SMP PREEMPT_DYNAMIC …
Tres opciones bastan para ver el oficio del configurador. CONFIG_HZ es la frecuencia del tic del tema 19: 1000 favorece la respuesta, y un servidor de cálculo elegiría 100 o 250. CONFIG_NR_CPUS es la cantidad máxima de procesadores admitida: 8192 en una distribución que debe funcionar en cualquier equipo; un sistema embebido de un solo núcleo pondría 1, y ahorraría memoria y código. Y PREEMPT_DYNAMIC indica que el grado en que el propio kernel puede ser desalojado, que es la diferencia entre un sistema orientado al rendimiento y uno orientado a la respuesta, se elige al arrancar, con un parámetro, sin recompilar.
13. Cuadro comparativo
La tabla siguiente reúne los tipos del tema. Las columnas centrales son las que definen a cada uno: qué pone primero y qué acepta perder.
| Tipo | Prioriza | Sacrifica | Planificación | Ejemplos |
|---|---|---|---|---|
| Por lotes | Rendimiento total | Tiempo de respuesta | Turnos largos, o un trabajo hasta que termine | Gestores de colas en clústeres de cálculo |
| Interactivo | Tiempo de respuesta y equidad | Garantías de plazo | Turnos de milisegundos, repartidos en proporción | Linux, Windows y macOS de escritorio |
| Tiempo real | Plazos y predecibilidad | Rendimiento y equidad | Prioridad estricta, con desalojo inmediato | FreeRTOS, VxWorks, QNX |
| Embebido | Tamaño, costo y consumo | Generalidad y, a menudo, protección | Según la función; con frecuencia, de tiempo real | Zephyr, Linux embebido |
| Móvil | Batería, respuesta táctil y aislamiento | El control del usuario sobre los programas | Interactiva, atenta al consumo | Android, iOS |
| Servidor y nube | Rendimiento, disponibilidad y aislamiento entre clientes | Interfaz de usuario | Orientada al total | Distribuciones de servidor, hipervisores |
| Distribuido | Escala y tolerancia a fallas | Simplicidad | Entre máquinas, además de dentro de cada una | Kubernetes sobre Linux |
Las fronteras no son rígidas. Un teléfono es móvil, embebido y de tiempo real flexible a la vez; un servidor ejecuta trabajos por lotes mientras atiende pedidos interactivos. Los tipos son, más que cajas donde ubicar cada sistema, direcciones hacia las que se inclina un diseño. En el tema 24 pasamos de lo que un sistema optimiza a cómo está construido por dentro su kernel.
14. Resumen
- Todos los sistemas operativos usan los mismos mecanismos. Se diferencian en qué objetivo ponen primero, porque los objetivos se oponen entre sí.
- Los sistemas por lotes ejecutan trabajos encolados sin intervención humana y buscan el rendimiento total. Siguen vigentes en el cálculo científico y en el procesamiento nocturno.
- Los sistemas interactivos reparten la CPU en turnos breves para responder de inmediato, con equidad y sin garantías exactas.
- El valor
niceinclina el reparto de un sistema interactivo sin dejar a ningún proceso sin turno. - En un sistema de tiempo real, un resultado tardío es incorrecto. Se exige que el peor caso esté acotado, no que el promedio sea bajo.
- El tiempo real es estricto si incumplir un plazo es una falla, y flexible si solo degrada la calidad.
- La latencia de un programa depende de la carga con la política normal, y casi no depende de ella con una política de tiempo real.
- Los sistemas embebidos se construyen para una función y un hardware limitado. En los más pequeños no hay modos ni protección de memoria.
- Los sistemas móviles se organizan en torno a la batería y al aislamiento de las aplicaciones, y deciden por sí mismos cuándo termina un programa.
- En servidores, las máquinas virtuales comparten el hardware mediante un hipervisor, y los contenedores comparten además el kernel.
- Un sistema distribuido presenta varias máquinas como una. Hoy se construye por encima de sistemas operativos convencionales.
- Linux cubre casi todos los tipos gracias a su configuración al compilar, al arrancar y en el espacio de usuario.
15. Preguntas de repaso
Intenta responder cada una antes de abrir la respuesta.
1. ¿Por qué no puede existir un sistema operativo óptimo para todos los usos?
Porque los objetivos se contraponen. Maximizar el rendimiento total pide interrumpir poco, y responder rápido pide interrumpir mucho; garantizar plazos exige reservar capacidad y renunciar a la equidad; aislar los programas cuesta rendimiento y tamaño. Cada tipo elige qué priorizar.
2. ¿Qué mide el éxito de un sistema por lotes, y qué el de uno interactivo?
En el primero, la cantidad de trabajo completado por unidad de tiempo. En el segundo, el tiempo que tarda en reaccionar ante cada acción del usuario.
3. Dos copias de bucle comparten un procesador, una con nice 0 y otra con 19. ¿Por qué la segunda no queda en cero?
Porque el planificador convierte la cortesía en un peso y reparte el tiempo en proporción a los pesos. El proceso cortés tiene un peso muy pequeño, pero no nulo, y recibe turnos breves. Si el otro termina, usa todo el procesador.
4. ¿Por qué «tiempo real» no significa «rápido»?
Porque lo que se exige es cumplir un plazo siempre, es decir, que el peor caso esté acotado y sea conocido. Un sistema puede ser muy rápido en promedio y fallar un plazo ocasionalmente; ese no sirve. Otro puede ser más lento pero predecible, y sí sirve.
5. Clasifica como tiempo real estricto o flexible: un marcapasos, una videollamada, el control de un robot de soldadura, un reproductor de música.
El marcapasos y el robot son de tiempo real estricto: incumplir un plazo es una falla con posibles daños. La videollamada y el reproductor son de tiempo real flexible: un retraso ocasional produce un salto en la imagen o en el sonido, y nada más.
6. ¿Por qué un programa de tiempo real pide su memoria por adelantado?
Porque, si la memoria se entrega al primer acceso, ese acceso provoca un fallo de página cuya duración no se puede acotar, sobre todo si hay que leer del disco. Con la memoria ya asignada y fija, cada acceso tarda un tiempo conocido.
7. En el experimento de latencia, ¿por qué el peor caso empeora tanto con carga y la política normal?
Porque al vencer la pausa el programa solo pasa a estar listo, y debe esperar a que el planificador le dé un turno entre los procesos que ocupan los procesadores. La mayoría de las veces es pronto; algunas, tarda milisegundos.
8. ¿Qué hace distinto SCHED_FIFO, y qué riesgo tiene?
Da al proceso prioridad estricta sobre todos los procesos normales: en cuanto está listo, desaloja a quien tenga la CPU. El riesgo es que, si no se bloquea nunca, deja sin procesador a los demás.
9. ¿Qué consecuencia tiene que un microcontrolador no tenga unidad de gestión de memoria?
Que no hay espacios de direcciones separados ni protección. El kernel y las tareas comparten la memoria, y un error en cualquiera de ellas puede corromper a las demás y al propio sistema.
10. ¿Cómo aísla Android a las aplicaciones entre sí?
Asigna a cada aplicación un usuario distinto del kernel de Linux. Los permisos entre usuarios, pensados originalmente para separar personas, impiden que una aplicación lea los archivos de otra.
11. ¿Cuál es la diferencia esencial entre una máquina virtual y un contenedor?
Cada máquina virtual tiene su propio kernel y funciona sobre un hipervisor que simula el hardware. Los contenedores comparten el kernel del anfitrión, que da a cada uno una vista separada de los recursos. Por eso el contenedor es más liviano y su aislamiento, menor.
12. ¿Qué tres problemas tiene un sistema distribuido que no tiene una máquina sola?
Las fallas parciales, en que una parte deja de funcionar y el resto no; la falta de un reloj común, que dificulta ordenar los sucesos; y la demora de la comunicación por red, muchísimo mayor que la de un acceso a memoria.
13. ¿Cómo puede el mismo kernel servir para un supercomputador y para un enrutador?
Porque se configura al compilarlo, eligiendo qué funciones y drivers incluye; se ajusta al arrancar y en marcha con parámetros; y se combina con un espacio de usuario distinto en cada caso.
Para practicar
- Repite el experimento de la sección 5 con cortesía 5, 10 y 15 en lugar de 19. ¿Cómo cambia el reparto? ¿Es proporcional al valor?
- Lanza las dos copias de
buclede la sección 5 sintaskset. ¿Qué porcentaje recibe cada una, y por qué la cortesía deja de notarse? - Ejecuta
latenciadiez veces en reposo y anota el peor retraso de cada una. ¿Cuánto varía? ¿Y el promedio? - Repite el experimento de la sección 7 lanzando
latenciaconnice -n -20mediantesudo, en lugar dechrt. ¿Mejora tanto como con la política de tiempo real? - Consulta la política de planificación de tu shell con
chrt -p $$. Luego busca procesos de tiempo real en tu sistema conps -eo pid,cls,rtprio,comm | grep -E 'FF|RR'. ¿Qué son? - Ejecuta
systemd-detect-virtyhostnamectlen tu entorno. ¿Qué informan sobre el tipo de equipo y la virtualización? - Cuenta las opciones activas de tu kernel con
grep -c '=y' /boot/config-$(uname -r)y las compiladas como módulo congrep -c '=m'. ¿Qué te dice la proporción sobre una distribución de propósito general? - Elige cinco aparatos de tu casa que contengan una computadora. Para cada uno, estima en cuál de los tres escalones de la sección 8 está y si tiene requisitos de tiempo real.
- Para cada uno de estos casos, indica el tipo de sistema más adecuado y qué objetivo prioriza: el control de un ascensor, la liquidación de sueldos de una empresa, un reloj inteligente, un servicio de correo para un millón de usuarios.