← Planificación de la CPU Bloque 1 · Por qué hay que planificar la CPU · Tema 5 de 44

Tema 5

Planificación apropiativa y no apropiativa

Hasta ahora hemos visto que el planificador decide quién recibe la CPU. Pero ¿puede quitarle la CPU a un proceso que no la ha soltado voluntariamente? Esa capacidad se llama apropiación (preemption), y cambia radicalmente cómo funciona el sistema. En este tema verás los cuatro momentos en que el sistema decide, qué ocurre cuando puede quitarle la CPU a un proceso, y las ventajas y desventajas de cada modelo.

1. Que es la apropiacion

La apropiacion (preemption) es la capacidad del sistema operativo de quitarle la CPU a un proceso que esta ejecutandose, sin que el proceso la haya soltado voluntariamente. El proceso se interrumpe, se guarda su estado, y se le da la CPU a otro proceso. Cuando el proceso interrumpido vuelve a ejecutarse, continua desde donde se quedo.

Sin apropiacion, un proceso que no se bloquea ni termina puede usar la CPU indefinidamente. Con apropiacion, el sistema puede garantizar que todos los procesos reciben tiempo de CPU, incluso si uno de ellos es un bucle infinito.

La apropiacion se basa en el temporizador del hardware: el nucleo programa el temporizador para que genere una interrupcion periodicamente (cada quantum). Cuando la interrupcion ocurre, el nucleo invoca al planificador, que puede decidir cambiar de proceso.

La apropiacion es la diferencia entre tiempo compartido y tiempo real

Sin apropiacion, un proceso de calculo pesado bloquearia a todos los demas. Con apropiacion, el sistema puede interrumpir al proceso pesado y dar turno a los procesos interactivos. La apropiacion es lo que hace que un sistema de tiempo compartido sea utilizable.

2. Planificacion no apropiativa

En la planificacion no apropiativa (non-preemptive), una vez que un proceso recibe la CPU, la retiene hasta que termina o se bloquea voluntariamente. El sistema no puede quitarle la CPU.

Los momentos en que el sistema puede cambiar de proceso son solo los voluntarios: cuando el proceso termina, se bloquea en E/S, o cede la CPU explicitamente.

Las caracteristicas son:

Los sistemas no apropiativos son adecuados para:

Ejemplos de algoritmos no apropiativos: FCFS (First-Come First-Served), SJF no apropiativo, planificacion por prioridades no apropiativa.

3. Planificacion apropiativa

En la planificacion apropiativa (preemptive), el sistema puede quitarle la CPU a un proceso que esta ejecutandose, incluso si no ha terminado ni se ha bloqueado. Esto se hace cuando expira el quantum, cuando llega un proceso de mayor prioridad, o cuando una interrupcion lo requiere.

La apropiacion requiere:

Las caracteristicas son:

Los sistemas apropiativos son adecuados para:

Ejemplos de algoritmos apropiativos: Round Robin, SRTF (SJF apropiativo), planificacion por prioridades apropiativa, CFS.

4. Los cuatro momentos de decision

El sistema operativo toma decisiones de planificacion en cuatro momentos. La diferencia entre un sistema apropiativo y uno no apropiativo esta en cuantos de estos momentos estan disponibles:

MomentoDescripcionNo apropiativoApropiativo
1. Un proceso terminaEl proceso que estaba en la CPU termina. Se elige otro.SiSi
2. Un proceso se bloqueaEl proceso pide E/S y se bloquea. Se elige otro.SiSi
3. Un proceso se creaSe crea un proceso nuevo. Se puede elegir ejecutarlo inmediatamente o esperar.Si (opcional)Si (opcional)
4. Un proceso se desbloqueaUn proceso bloqueado se vuelve listo. Se puede elegir ejecutarlo inmediatamente.NoSi

Los momentos 1 y 2 son voluntarios: el proceso cede la CPU. Los momentos 3 y 4 son involuntarios: el sistema decide cambiar de proceso.

En un sistema no apropiativo, solo se puede cambiar de proceso en los momentos 1 y 2 (voluntarios). En un sistema apropiativo, tambien se puede cambiar en los momentos 3 y 4 (involuntarios), y ademas cuando expira el quantum.

La diferencia clave es el momento 4: cuando un proceso bloqueado se desbloquea (por ejemplo, cuando llega un paquete de red o termina una lectura de disco), en un sistema apropiativo se puede interrumpir al proceso actual y ejecutar el que se desbloqueo. En un sistema no apropiativo, hay que esperar a que el proceso actual termine o se bloquee.

El momento 4 es la diferencia

En un sistema apropiativo, cuando un proceso de mayor prioridad se desbloquea, puede interrumpir al proceso actual. En un sistema no apropiativo, debe esperar. Esta es la diferencia fundamental entre ambos modelos.

5. Apropiativo vs no apropiativo

CaracterísticaNo apropiativoApropiativo
Cuándo cambia de procesoSolo cuando el proceso termina o se bloquea.También cuando expira el quantum o llega un proceso de mayor prioridad.
ComplejidadMenor (no necesita temporizador).Mayor (necesita temporizador e interrupciones).
OverheadMenor (menos cambios de contexto).Mayor (cambios forzados por quantum).
RespuestaPeor (un proceso corto puede esperar a uno largo).Mejor (los procesos cortos reciben la CPU rápidamente).
EquidadMenor (un proceso puede monopolizar la CPU).Mayor (todos reciben turnos).
PredicibilidadMayor (el comportamiento es más predecible).Menor (el timing afecta el resultado).
Usado porSistemas por lotes, sistemas de tiempo real simples.Sistemas de tiempo compartido, Linux, Windows, macOS.

La elección entre apropiativo y no apropiativo depende del caso de uso. Los sistemas de propósito general (Linux, Windows, macOS) usan apropiación porque la respuesta y la equidad son más importantes que la simplicidad. Los sistemas por lotes y algunos sistemas de tiempo real usan no apropiación porque la simplicidad y la predicibilidad son más importantes.

6. Apropiación y el quantum

En un sistema apropiativo, el quantum (o time slice) es el intervalo de tiempo que un proceso puede usar la CPU antes de que el planificador lo interrumpa. Es el mecanismo que hace posible el tiempo compartido.

El quantum se configura en el sistema operativo y puede variar:

El quantum es un compromiso:

El quantum es el parámetro clave

El quantum determina el balance entre respuesta y overhead. Linux con CFS ajusta el quantum dinámicamente: con pocos procesos, cada uno recibe un quantum largo (buena respuesta, poco overhead). Con muchos procesos, cada uno recibe un quantum corto (más overhead, pero más equitativo).

7. Apropiación en Linux

Linux es un sistema apropiativo. El núcleo puede quitarle la CPU a un proceso en cualquier momento, no solo cuando se bloquea o termina.

La apropiación en Linux se implementa con:

Linux también soporta no apropiación para casos específicos:

En Linux, la apropiación se puede deshabilitar temporalmente en secciones críticas del núcleo (con preempt_disable()). Esto evita que una interrupción cambie de proceso mientras se manipulan estructuras internas del núcleo.

terminal - verificar apropiación en Linux

$ grep CONFIG_PREEMPT /boot/config-$(uname -r)
CONFIG_PREEMPT=y  # o CONFIG_PREEMPT_VOLUNTARY=y o CONFIG_PREEMPT_NONE=y

Linux se puede compilar con diferentes niveles de apropiación:

8. Ventajas y desventajas

La apropiación tiene ventajas y desventajas:

VentajaDesventaja
Mejor respuesta para procesos interactivos.Overhead de cambios de contexto forzados.
Equidad: todos los procesos reciben turnos.Complejidad del núcleo (manejo de interrupciones).
Un proceso no puede monopolizar la CPU.Menor predicibilidad del timing.
Mejor para sistemas de tiempo compartido.Requiere hardware con temporizador.

La no apropiación también tiene ventajas:

VentajaDesventaja
Simplicidad del núcleo.Un proceso puede monopolizar la CPU.
Menor overhead (menos cambios de contexto).Peor respuesta para procesos interactivos.
Mayor predicibilidad.Menor equidad.
Adecuado para sistemas por lotes.No adecuado para sistemas interactivos.

En la práctica, todos los sistemas de propósito general (Linux, Windows, macOS) usan apropiación. Los sistemas por lotes y algunos sistemas embebidos usan no apropiación.

9. Un programa que demuestra la diferencia

El siguiente programa ejecuta un proceso que usa la CPU sin parar, y otro que hace E/S. Con apropiación, el proceso de E/S recibe la CPU entre los turnos del proceso de CPU. Sin apropiación, el proceso de CPU monopolizaría la CPU.

apropiacion_demo.c

#define _POSIX_C_SOURCE 200809L
#include 
#include 
#include 
#include 

static double tiempo_ms(void)
{
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return ts.tv_sec * 1000.0 + ts.tv_nsec / 1e6;
}

int main(void)
{
    /* Proceso limitado por CPU: usa la CPU sin parar */
    pid_t pid_cpu = fork();
    if (pid_cpu == 0) {
        volatile unsigned long x = 0;
        for (unsigned long i = 0; i < 2000000000UL; i++) x++;
        _exit(0);
    }

    /* Proceso limitado por E/S: hace E/S cada 100 ms */
    pid_t pid_io = fork();
    if (pid_io == 0) {
        for (int i = 0; i < 10; i++) {
            printf("I/O: iteracion %d\n", i);
            fflush(stdout);
            usleep(100000);  /* 100 ms */
        }
        _exit(0);
    }

    /* Padre: esperar a ambos */
    waitpid(pid_cpu, NULL, 0);
    waitpid(pid_io, NULL, 0);
    printf("Ambos terminaron\n");
    return 0;
}
terminal - ejecutar apropiacion_demo

$ gcc -std=c17 -Wall -Wextra -o apropiacion_demo apropiacion_demo.c
$ ./apropiacion_demo
I/O: iteracion 0
I/O: iteracion 1
I/O: iteracion 2
...
I/O: iteracion 9
Ambos terminaron

El proceso de E/S se ejecuta cada 100 ms, aunque el proceso de CPU use la CPU sin parar. Esto es porque el sistema es apropiativo: interrumpe al proceso de CPU y da turno al proceso de E/S. Sin apropiación, el proceso de E/S tendría que esperar a que el proceso de CPU terminara.

Se puede observar la apropiación con strace o con perf sched:

terminal - observar apropiación con perf sched

$ perf sched record ./apropiacion_demo
$ perf sched latency
 Task                  |   Runtime ms  | Switches | Avg delay ms | Max delay ms |
 ----------------------+---------------+----------+--------------+--------------+
 apropiacion_demo:CPU  |      2000.000 |       50 |        0.004 |        0.012 |
 apropiacion_demo:IO   |        10.000 |       10 |        0.002 |        0.008 |

El proceso de CPU se interrumpió 50 veces (cambios involuntarios). El proceso de E/S se ejecutó 10 veces (una por iteración). La latencia de despacho fue de ~4 us en promedio.

10. Resumen

11. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. Que es la apropiacion?

La capacidad del sistema operativo de quitarle la CPU a un proceso que esta ejecutandose, sin que el proceso la haya soltado voluntariamente.

2. Que es un sistema no apropiativo?

Un sistema donde un proceso retiene la CPU hasta que termina o se bloquea. El sistema no puede interrumpirlo.

3. Que es un sistema apropiativo?

Un sistema donde el sistema puede quitarle la CPU a un proceso en cualquier momento (quantum, prioridad, interrupcion).

4. Cuales son los cuatro momentos de decision?

Terminacion, bloqueo, creacion y desbloqueo. El momento 4 (desbloqueo) es la diferencia clave.

5. Que es el quantum?

El intervalo de tiempo que un proceso puede usar la CPU antes de ser interrumpido. Es el mecanismo del tiempo compartido.

6. Que niveles de apropiacion tiene Linux?

CONFIG_PREEMPT_NONE (no apropiativo), CONFIG_PREEMPT_VOLUNTARY (voluntario), CONFIG_PREEMPT (completo), CONFIG_PREEMPT_RT (tiempo real).

7. Cuales son las ventajas de la apropiacion?

Mejor respuesta, mayor equidad, un proceso no puede monopolizar la CPU.

8. Cuales son las desventajas de la apropiacion?

Overhead de cambios de contexto, complejidad del nucleo, menor predicibilidad.

9. Por que los sistemas de tiempo real usan apropiacion?

Para garantizar que un proceso de mayor prioridad se ejecute inmediatamente cuando se vuelve listo, cumpliendo plazos estrictos.

10. Que es SCHED_BATCH en Linux?

Una politica de planificacion que minimiza las interrupciones para procesos de calculo por lotes. Es una forma de no apropiacion dentro de un sistema apropiativo.

Para practicar

  1. Compila y ejecuta apropiacion_demo.c. Observa como el proceso de E/S se ejecuta entre los turnos del proceso de CPU.
  2. Verifica el nivel de apropiacion de tu kernel con grep CONFIG_PREEMPT /boot/config-$(uname -r).
  3. Usa perf sched para observar la apropiacion en accion.
  4. Escribe un programa que demuestre la diferencia entre apropiativo y no apropiativo (usando SCHED_BATCH).
  5. Investiga el parche PREEMPT_RT y como reduce la latencia de despacho.
  6. Compara la respuesta del sistema con CONFIG_PREEMPT_NONE vs CONFIG_PREEMPT.