← Planificación de la CPU Bloque 10 · El planificador de Linux · Tema 37 de 44

Tema 37

Prioridades y nice

En la clase fair de Linux, la prioridad de un proceso se controla con el valor nice. Un nice bajo significa mayor prioridad; un nice alto significa menor. En este tema verás qué es el nice, cómo se relaciona con la prioridad interna del planificador, la tabla de pesos que usa CFS y cómo se observa y modifica en un sistema real.

1. Qué es el nice

El nice es un valor que indica la «amabilidad» de un proceso: cuánta CPU está dispuesto a ceder a otros procesos. Un nice bajo (negativo) significa que el proceso es «poco amable» y quiere más CPU. Un nice alto (positivo) significa que el proceso es «amable» y cede CPU a otros.

El nombre viene del comando nice, que se usaba para lanzar procesos con una prioridad ajustada: «ser nice» con los demás procesos. En Unix, el nice es una forma de que el usuario indique la importancia relativa de sus procesos.

El nice es un atributo del proceso que el usuario puede modificar (con nice y renice). El planificador (CFS) lo usa para calcular la prioridad interna del proceso y repartir la CPU en consecuencia.

Nice no es prioridad absoluta

El nice solo afecta a la clase fair (SCHED_OTHER). Los procesos de tiempo real (SCHED_FIFO, SCHED_RR) no usan nice: tienen prioridades del 1 al 99. Un proceso nice -20 (máxima prioridad en fair) se ejecuta después de cualquier proceso de tiempo real.

2. El rango de nice

El nice va de -20 a +19:

NiceSignificadoUso típico
-20Máxima prioridad (menos nice)Procesos críticos del usuario.
-10Alta prioridadProcesos importantes.
0Prioridad por defectoLa mayoría de los procesos.
+10Baja prioridadProcesos en segundo plano.
+19Mínima prioridad (más nice)Procesos de baja prioridad (backup, indexación).

Un usuario normal solo puede aumentar el nice (hacer el proceso más amable), no disminuirlo. Para disminuir el nice (aumentar la prioridad), se necesita privilegio (root o CAP_SYS_NICE).

La diferencia entre nice -20 y nice +19 es enorme: un proceso con nice -20 recibe aproximadamente 40 veces más CPU que uno con nice +19 (según la tabla de pesos).

3. La prioridad interna

CFS no usa el nice directamente. Lo convierte en una prioridad interna (prio) que va de 100 a 139:

prio = 120 + nice

Así, nice -20 → prio 100 (máxima prioridad en fair), y nice +19 → prio 139 (mínima prioridad en fair). La prioridad por defecto (nice 0) es prio 120.

La prioridad interna se usa para calcular el peso del proceso, que determina cuánta CPU recibe.

4. La tabla de pesos

CFS usa una tabla de pesos que asigna un peso a cada prioridad interna. El peso determina la fracción de CPU que recibe el proceso:

NicePrioPesoFracción de CPU (relativa a nice 0)
-2010088761≈ 40× (más CPU)
-1510529154≈ 13×
-101109548≈ 4,3×
-51153121≈ 1,4×
012010241× (base)
+5125335≈ 0,33×
+10130110≈ 0,11×
+1513536≈ 0,035×
+1913915≈ 0,015×

Los pesos no son lineales: cada nivel de nice cambia el peso por un factor de aproximadamente 1,25. Esto significa que cada nivel de nice da un 25 % más (o menos) de CPU que el anterior.

La tabla de pesos está definida en el código del núcleo (kernel/sched/core.c) y es fija. No se puede modificar sin recompilar el núcleo.

Los pesos son multiplicativos

Cada nivel de nice cambia el peso por un factor de ~1,25. Un proceso con nice -5 (peso 3121) recibe aproximadamente 3 veces más CPU que uno con nice +5 (peso 335), porque 3121/335 ≈ 9,3. Pero respecto al nice 0, nice -5 recibe 3 veces más y nice +5 recibe 0,33 veces.

5. Cómo funciona el nice en CFS

CFS usa el peso para calcular el vruntime (tiempo virtual) de cada proceso. El vruntime se acumula a medida que el proceso se ejecuta, pero la velocidad de acumulación depende del peso:

vruntime += tiempo_real × (peso_base / peso_proceso)

Donde peso_base es el peso de nice 0 (1024). Un proceso con mayor peso (nice más bajo) acumula vruntime más lentamente, lo que significa que se ejecuta más antes de que su vruntime alcance el del siguiente proceso.

Por ejemplo, un proceso con nice -5 (peso 3121) acumula vruntime a un tercio de la velocidad de uno con nice 0 (peso 1024). Así, recibe aproximadamente 3 veces más CPU.

El reparto es proporcional a los pesos: si hay dos procesos, uno con peso 1024 (nice 0) y otro con peso 3121 (nice -5), el primero recibe 1024/(1024+3121) = 25 % de la CPU y el segundo recibe 3121/(1024+3121) = 75 %.

6. Un ejemplo desarrollado

Dos procesos con nice 0 y nice -5, ambos con ráfaga 10, llegando en 0:

ProcesoNicePesoFracción de CPU
P1010241024/(1024+3121) = 24,7 %
P2-531213121/(1024+3121) = 75,3 %

En CFS, P2 (nice -5) recibe aproximadamente 3 veces más CPU que P1 (nice 0). Si ambos necesitan 10 unidades de CPU, P2 termina en 10/0,753 ≈ 13,3 unidades de tiempo, y P1 en 10/0,247 ≈ 40,5 unidades.

El Gantt sería algo como: P2, P2, P2, P1, P2, P2, P2, P1, ... (P2 recibe 3 turnos por cada turno de P1).

7. Observar y modificar en Linux

terminal · nice y prioridad
# Ver el nice de los procesos
$ ps -o pid,ni,comm -p $$
    PID  NI COMMAND
   453   0 bash

# Lanzar un proceso con nice +10
$ nice -n 10 ./mi_programa

# Lanzar con nice -5 (requiere privilegio)
$ sudo nice -n -5 ./mi_programa

# Ver la prioridad interna (prio) en /proc
$ grep prio /proc/self/sched
prio                                         :                  120

La columna NI de ps muestra el nice. La prioridad interna (prio) se lee de /proc/PID/sched y es 120 + nice.

8. Usar renice

renice permite cambiar el nice de un proceso en ejecución:

terminal · renice
# Cambiar el nice de un proceso a +10
$ renice -n 10 -p 1234
1234 (process ID) old priority 0, new priority 10

# Cambiar el nice de todos los procesos de un usuario
$ renice -n 5 -u usuario

# Cambiar el nice de un grupo de procesos
$ renice -n -3 -g 1234

Un usuario normal solo puede aumentar el nice (hacer el proceso más amable). Para disminuir el nice (aumentar la prioridad), se necesita privilegio (root).

9. Propiedades

Propiedad¿La cumple?Comentario
FlexibilidadSíEl usuario puede ajustar la prioridad de sus procesos.
Granularidad40 nivelesDe -20 a +19.
PredecibilidadSíEl reparto es proporcional a los pesos.
FairnessParcialEl reparto es proporcional, no igual.
Uso realSíTodos los procesos normales de Linux.

10. Simulador interactivo

Este simulador muestra cómo el nice afecta al reparto de CPU. Dos procesos con nice distintos compiten por la CPU:

Simulador · nice y reparto de CPU

ProcesoNicePesoFracción de CPUInicioFinRetorno

11. Resumen

12. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Qué es el nice?

Un valor que indica la amabilidad de un proceso: cuánta CPU está dispuesto a ceder.

2. ¿Cuál es el rango del nice?

De -20 (máxima prioridad) a +19 (mínima prioridad).

3. ¿Cómo se calcula la prioridad interna a partir del nice?

prio = 120 + nice.

4. ¿Qué peso tiene un proceso con nice 0?

1024.

5. ¿Qué peso tiene un proceso con nice -20?

88761.

6. ¿Cómo afecta el peso al vruntime?

El vruntime se acumula a velocidad inversamente proporcional al peso: mayor peso = acumulación más lenta = más CPU.

7. ¿Un usuario normal puede disminuir el nice?

No. Solo puede aumentarlo. Para disminuirlo se necesita privilegio.

8. ¿Qué comando se usa para cambiar el nice de un proceso en ejecución?

renice.

9. ¿Afecta el nice a los procesos de tiempo real?

No. Solo afecta a la clase fair (SCHED_OTHER).

10. ¿Dónde se define la tabla de pesos?

En el código del núcleo (kernel/sched/core.c).

Para practicar

  1. Lanza dos procesos con nice 0 y nice 10 y compara el tiempo de CPU que reciben.
  2. Usa renice para cambiar el nice de un proceso en ejecución y observa el efecto.
  3. Calcula la fracción de CPU para nice -10 y nice +10.
  4. Explica por qué los pesos no son lineales.
  5. Investiga cómo se define la tabla de pesos en el código del núcleo.
  6. Modifica el simulador para añadir un tercer proceso con nice distinto.