1. El framework de planificación de Linux
El planificador de Linux (desde el núcleo 2.6.23) se basa en un framework de clases de planificación. En lugar de un solo algoritmo, hay varias clases, cada una con su propio algoritmo. El planificador selecciona el proceso de mayor prioridad entre todas las clases.
El framework tiene estas características:
- Modularidad: cada clase es un módulo independiente con su propio algoritmo. El código de cada clase está en
kernel/sched/. - Prioridad entre clases: las clases tienen un orden de prioridad fijo. La clase stop tiene la mayor prioridad, luego deadline, luego real-time, luego fair, y finalmente idle.
- Selección global: el planificador selecciona el proceso de mayor prioridad entre todas las clases, no dentro de una sola clase. Esto se hace en la función
pick_next_task(). - Extensibilidad: se pueden añadir nuevas clases sin modificar las existentes. El framework usa una lista de clases ordenadas por prioridad.
Este diseño permite que Linux soporte diferentes tipos de carga de trabajo (tiempo real, interactivo, por lotes) con un solo planificador. Antes de este framework, Linux usaba un solo planificador con 140 prioridades, lo que era difícil de mantener.
El planificador de Linux es un framework, no un algoritmo. Cada clase tiene su propio algoritmo, y el planificador selecciona el proceso de mayor prioridad entre todas las clases. La función pick_next_task() recorre las clases en orden de prioridad y pregunta a cada una si tiene un proceso listo.
2. Las cinco clases
Linux tiene cinco clases de planificación, ordenadas por prioridad (de mayor a menor):
| Clase | Prioridad | Política | Descripción | Procesos de usuario |
|---|---|---|---|---|
| stop | Máxima | SCHED_STOP | Tareas del núcleo que deben ejecutarse inmediatamente. | No |
| deadline | Muy alta | SCHED_DEADLINE | Tareas con plazo (EDF). | Sí |
| real-time | Alta | SCHED_FIFO, SCHED_RR | Tareas de tiempo real. | Sí |
| fair | Normal | SCHED_OTHER, SCHED_BATCH, SCHED_IDLE | Tareas normales (CFS). | Sí |
| idle | Mínima | SCHED_IDLE | Tareas que solo se ejecutan cuando no hay nada más. | Sí (SCHED_IDLE) |
La clase stop tiene la mayor prioridad y se usa para tareas críticas del núcleo (como la migración de procesos entre CPUs). La clase idle tiene la menor prioridad y se usa para tareas que solo deben ejecutarse cuando el sistema está completamente ocioso.
3. Clase stop
La clase stop es la de mayor prioridad. Se usa para tareas del núcleo que deben ejecutarse inmediatamente, sin importar lo que esté haciendo la CPU. Estas tareas son:
- Migración de procesos: mover un proceso de un CPU a otro (migración activa).
- Balanceo de carga: migrar procesos para equilibrar la carga entre CPUs.
- Operaciones críticas del núcleo: que no pueden esperar (por ejemplo, la finalización de una interrupción).
La clase stop no tiene procesos de usuario. Solo el núcleo la usa internamente. Los procesos de esta clase se ejecutan con la CPU en modo núcleo y no pueden ser preemptados por ninguna otra clase.
La clase stop es necesaria porque algunas operaciones del núcleo deben ejecutarse inmediatamente para mantener la consistencia del sistema. Por ejemplo, si un proceso se está migrando de un CPU a otro, la migración debe completarse antes de que otro proceso acceda a los datos del proceso migrado.
4. Clase deadline
La clase deadline implementa SCHED_DEADLINE (EDF). Las tareas de esta clase tienen un plazo y el sistema garantiza que se cumple (si es posible).
Características:
- Prioridad por plazo: la tarea con el plazo más cercano se ejecuta primero.
- Apropiativo: si llega una tarea con plazo más cercano, interrumpe a la actual.
- Admisión controlada: el sistema verifica que el conjunto sea planificable antes de aceptar.
- Prioridad sobre real-time: una tarea deadline se ejecuta antes que una de real-time, incluso si la de real-time tiene prioridad 99.
- Parámetros: runtime, deadline, period (se especifican con sched_setattr).
La clase deadline es la más alta de las clases de usuario. Se usa para aplicaciones que necesitan garantías de plazo estrictas (sistemas de tiempo real blando).
5. Clase real-time
La clase real-time implementa SCHED_FIFO y SCHED_RR. Las tareas de esta clase tienen prioridades del 1 al 99.
Características:
- Prioridades fijas: del 1 al 99 (mayor = más prioridad).
- Apropiativo entre prioridades: un proceso de mayor prioridad interrumpe a uno de menor.
- Sin quantum (FIFO) o con quantum (RR): dentro de la misma prioridad.
- Sin garantías formales: a diferencia de deadline, no verifica la planificabilidad.
- Sin admisión controlada: cualquier proceso con privilegio puede usar SCHED_FIFO/RR.
La clase real-time es para aplicaciones que necesitan respuesta rápida pero no requieren garantías formales de plazo. Es el equivalente a RM (Rate Monotonic) en Linux.
Un proceso de tiempo real con prioridad 99 que no se bloquea puede monopolizar la CPU. Por eso, debe usarse con cuidado: solo para procesos críticos y breves.
6. Clase fair
La clase fair implementa SCHED_OTHER, SCHED_BATCH y SCHED_IDLE. Es la clase más usada: todos los procesos normales (shells, editores, servidores, compiladores) están en esta clase.
Características:
- CFS (Completely Fair Scheduler): reparte la CPU de forma equitativa según el vruntime.
- Prioridades dinámicas: basadas en el nice (nice -20 a +19).
- Sin garantías de tiempo real: es de propósito general.
- Tres políticas: SCHED_OTHER (normal), SCHED_BATCH (por lotes), SCHED_IDLE (solo cuando no hay nada más).
- Adaptabilidad: el vruntime se adapta al número de procesos y a sus pesos.
La clase fair es la que se estudia en detalle en los temas 37-41. CFS usa el vruntime para repartir la CPU de forma equitativa, y el árbol rojinegro para seleccionar el proceso con menor vruntime.
7. Clase idle
La clase idle es la de menor prioridad. Se usa para la tarea idle (la tarea que se ejecuta cuando no hay nada más que hacer). La tarea idle consume la CPU cuando no hay procesos listos, poniendo el procesador en estado de bajo consumo (halt o MWAIT).
La clase idle no tiene procesos de usuario. Solo el núcleo la usa internamente. La tarea idle es especial: no se planifica como un proceso normal; el núcleo la ejecuta automáticamente cuando no hay nada más.
La tarea idle es importante para el consumo de energía: cuando no hay trabajo, el procesador se pone en un estado de bajo consumo, reduciendo el consumo de energía.
8. El orden de las clases
El planificador selecciona el proceso de mayor prioridad entre todas las clases. El orden es:
| Orden | Clase | Condición | Ejemplo de proceso |
|---|---|---|---|
| 1 | stop | Si hay procesos stop listos. | migration/0 (migración de procesos) |
| 2 | deadline | Si no hay stop, pero hay deadline listos. | Proceso con SCHED_DEADLINE |
| 3 | real-time | Si no hay stop ni deadline, pero hay real-time listos. | Proceso con SCHED_FIFO prioridad 50 |
| 4 | fair | Si no hay clases superiores listas. | bash, firefox, gcc |
| 5 | idle | Si no hay nada más. | Tarea idle del núcleo |
Esto significa que un proceso de tiempo real (real-time) siempre se ejecuta antes que un proceso normal (fair), incluso si el proceso normal tiene nice -20 (máxima prioridad en la clase fair). Las clases tienen prioridad absoluta sobre las inferiores.
Un proceso de la clase real-time con prioridad 1 se ejecuta antes que un proceso de la clase fair con nice -20. Las clases tienen prioridad absoluta: no importa la prioridad dentro de la clase, la clase superior siempre gana. Esto es importante para los sistemas de tiempo real: garantiza que los procesos de tiempo real se ejecuten antes que los normales.
9. Las políticas por clase
Cada clase tiene una o más políticas:
| Clase | Política | Syscall | Descripción |
|---|---|---|---|
| stop | SCHED_STOP | — | Interna del núcleo. |
| deadline | SCHED_DEADLINE | sched_setattr | EDF con garantías. |
| real-time | SCHED_FIFO | sched_setscheduler | Sin quantum. |
| real-time | SCHED_RR | sched_setscheduler | Con quantum. |
| fair | SCHED_OTHER | sched_setscheduler | Normal (CFS). |
| fair | SCHED_BATCH | sched_setscheduler | Por lotes (menos preemptible). |
| fair | SCHED_IDLE | sched_setscheduler | Solo cuando no hay nada más. |
| idle | SCHED_IDLE (interno) | — | Tarea idle del núcleo. |
Las políticas se asignan con sched_setscheduler o sched_setattr. La herramienta chrt (tema 35) es un wrapper de estas syscalls.
10. Cómo asignar una política
Para asignar una política a un proceso, se usa la syscall sched_setscheduler o sched_setattr. La herramienta chrt simplifica esto:
# Asignar SCHED_FIFO con prioridad 50
$ chrt -f 50 ./mi_programa
# Asignar SCHED_RR con prioridad 50
$ chrt -r 50 ./mi_programa
# Asignar SCHED_OTHER (normal) con nice 0
$ chrt -o 0 ./mi_programa
# Asignar SCHED_BATCH
$ chrt -b 0 ./mi_programa
# Asignar SCHED_IDLE
$ chrt -i 0 ./mi_programa
# Cambiar la política de un proceso existente
$ chrt -p -f 80 1234
Las políticas de tiempo real (SCHED_FIFO, SCHED_RR, SCHED_DEADLINE) requieren privilegio (root o CAP_SYS_NICE). Las políticas normales (SCHED_OTHER, SCHED_BATCH, SCHED_IDLE) no requieren privilegio.
11. Observar en Linux
$ ps -e -o pid,cls,pri,ni,rtprio,comm | head -20
PID CLS PRI NI RTPRIO COMMAND
1 TS 19 0 - systemd
2 TS 19 0 - kthreadd
10 FF 139 - 99 migration/0
11 TS 19 0 - rcu_sched
453 TS 19 0 - bash
...
$ chrt -m
SCHED_OTHER min/max priority : 0/0
SCHED_FIFO min/max priority : 1/99
SCHED_RR min/max priority : 1/99
SCHED_BATCH min/max priority : 0/0
SCHED_IDLE min/max priority : 0/0
SCHED_DEADLINE min/max priority : 0/0
La columna CLS muestra la clase: TS (time sharing = fair), FF (FIFO = real-time), RR (round robin = real-time), DL (deadline = deadline), B (batch = fair), ID (idle = fair/idle).
12. Simulador interactivo
Este simulador muestra cómo las clases se ordenan por prioridad. Selecciona una clase y observa cómo afecta al orden de ejecución:
Simulador · clases de planificación
| Proceso | Clase | Prioridad | Inicio | Fin |
|---|
13. Resumen
- El planificador de Linux es un framework de clases, no un solo algoritmo.
- Las cinco clases son: stop, deadline, real-time, fair, idle.
- El orden de prioridad es: stop > deadline > real-time > fair > idle.
- stop: tareas críticas del núcleo (migración, balanceo).
- deadline: SCHED_DEADLINE (EDF con garantías).
- real-time: SCHED_FIFO y SCHED_RR (prioridades 1-99).
- fair: SCHED_OTHER, SCHED_BATCH, SCHED_IDLE (CFS).
- idle: tarea idle del núcleo.
- Las clases son absolutas: la clase superior siempre gana.
- Las políticas se asignan con sched_setscheduler o sched_setattr.
- chrt es un wrapper de estas syscalls.
14. Preguntas de repaso
Intenta responder cada una antes de abrir la respuesta.
1. ¿Cuáles son las cinco clases de planificación de Linux?
stop, deadline, real-time, fair, idle.
2. ¿Cuál es el orden de prioridad de las clases?
stop > deadline > real-time > fair > idle.
3. ¿Qué clase implementa SCHED_DEADLINE?
La clase deadline.
4. ¿Qué clase implementa SCHED_FIFO y SCHED_RR?
La clase real-time.
5. ¿Qué clase implementa SCHED_OTHER?
La clase fair.
6. ¿Qué clase tiene la mayor prioridad?
stop.
7. ¿Qué clase tiene la menor prioridad?
idle.
8. ¿Un proceso de tiempo real (prioridad 1) se ejecuta antes que uno normal (nice -20)?
Sí. Las clases son absolutas.
9. ¿Qué clase usa CFS?
La clase fair.
10. ¿Para qué se usa la clase stop?
Para tareas críticas del núcleo (migración, balanceo).
11. ¿Qué syscall se usa para asignar SCHED_DEADLINE?
sched_setattr.
12. ¿Qué syscall se usa para asignar SCHED_FIFO?
sched_setscheduler.
Para practicar
- Ejecuta ps -e -o pid,cls,pri,ni,comm y observa las clases.
- Lanza un proceso con chrt -f 50 y verifica que su clase es FF.
- Explica por qué las clases son absolutas.
- Investiga cómo el núcleo selecciona el proceso de mayor prioridad.
- Compara SCHED_BATCH con SCHED_OTHER.
- Explica para qué se usa la clase idle.