🐧 FSO — Repaso de última hora

Viernes 3 jul · 15:00 · Edif. ARQUITECTURA, labs D08 (LQ-2), E05 (LQ-D), E06 (LQ-C) · llega 14:45
⚠️ REGLA DE ORO: JUSTIFICA TODAS las respuestas de los ejercicios. Un resultado sin justificar = NULO. En el test no arriesgues a lo loco.
🎯 Para aprobar: teoría ≥6/10 (tu PAC es 0, no hay colchón) y práctico ≥2/3. Nota final = 0,75 × (TEO + PRA). Son pruebas separadas la misma tarde: preséntate a las dos.

⏱️ PLANIFICACIÓN (cae seguro)

TR (retorno) = TF − llegada
TE (espera) = TR − ráfaga
TE también = instante en que EMPIEZA − llegada (si no lo interrumpen) ← comprobación
Reglas de cada algoritmo:
RR numérico (examen 2019): N procesos, ráfaga B, Q=1, todos llegan en 0:
Retorno del 1º = (B−1)·N + 1
Vaciado de la cola = N·B
Cambios de contexto ≈ N·B
Espera media = (B−1)·N + (N+1)/2 − B
Ej. real: N=20, B=2 → 21 ms · 40 ms · ~40 · 28,5 ms

🧠 MEMORIA (cae seguro)

bits de offset = log₂(tamaño de página)
nº páginas lógicas = 2^(bits lógicos − offset)
nº marcos físicos = 2^(bits físicos − offset)

página = dirección ÷ tamaño (división entera)
offset = dirección mod tamaño
FÍSICA = marco × tamaño + offset (el offset NO cambia)
Ejemplo real 2019: lógicas 48 bits, físicas 32, página 64 KiB (=2¹⁶) → offset 16 bits → 2³² páginas y 2¹⁶ = 65 536 marcos.
TLB (tiempo efectivo):
T = h·T_RAM + (1−h)·(niveles+1)·T_RAM
Ej. 2019: 0,95·50 + 0,05·(3·50) = 55 ns (2 niveles → ×3 en el fallo)
Reemplazo de páginas (haz la tabla columna a columna): Preguntas cortas que se repiten:

⚡ CONCURRENCIA (cae seguro)

Sección crítica — 3 propiedades (para "analiza este algoritmo"):
  1. Exclusión mutua: nunca dos dentro.
  2. Progreso: si nadie está dentro, no se bloquea a quien quiere entrar.
  3. Espera limitada: no te pueden adelantar infinitas veces.
Método: busca UN entrelazado que rompa una propiedad → incorrecto.
Peterson correcto: flag[i]=true; turn=j; while(flag[j] && turn==j); — si falta el turn=j ANTES del while, FALLA la exclusión mutua (cayó en 2019).
EL problema estrella (depósito/surtidor/impresora — 100% de extraordinarias):
float cantidad = 0;
pthread_mutex_t m; pthread_cond_t cv;

void sacar(float L) {
    pthread_mutex_lock(&m);
    while (cantidad < L)            // WHILE, nunca if
        pthread_cond_wait(&cv, &m); // duerme y SUELTA el mutex
    cantidad -= L;
    pthread_mutex_unlock(&m);
}
void poner(float L) {
    pthread_mutex_lock(&m);
    cantidad += L;
    pthread_cond_broadcast(&cv);    // despierta a TODOS
    pthread_mutex_unlock(&m);
}
Por qué: while (re-comprobar al despertar) · wait suelta el mutex mientras duerme · broadcast porque esperan cantidades distintas.
Semáforos — productor/consumidor: mutex=1, vacios=N, llenos=0.
Productor: wait(vacios) → wait(mutex) → meter → signal(mutex) → signal(llenos)
Consumidor: wait(llenos) → wait(mutex) → sacar → signal(mutex) → signal(vacios)
Interbloqueo (Coffman, las 4 a la vez): exclusión mutua · retención y espera · sin expropiación · espera circular. Romper UNA lo previene.

🛠️ PRÁCTICO (50 min, PC Linux, ≥2/3)

lanza_hijos.c (cayó tal cual en el parcial):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
    int n = atoi(argv[1]);
    for (int i = 0; i < n; i++) {
        pid_t pid = fork();
        if (pid == 0) {                    // HIJO
            printf("Hijo %d: PID %d\n", i, getpid());
            exit(0);                       // ¡SIN ESTO, BOMBA DE PROCESOS!
        }
    }
    for (int i = 0; i < n; i++) wait(NULL);
    return 0;
}
fork() → 0 al hijo, PID del hijo al padre, −1 error. Padre e hijo NO comparten variables (copias). Los hilos SÍ comparten.
copiar fichero:
int fo = open("orig.txt", O_RDONLY);
int fd = open("dest.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
char buf[512]; ssize_t n;
while ((n = read(fo, buf, sizeof(buf))) > 0)
    write(fd, buf, n);              // n, ¡NO sizeof(buf)!
close(fo); close(fd);
read devuelve 0 al final del fichero, −1 error. Cabeceras: fcntl.h (open) y unistd.h (read/write/close).
hilos: pthread_create(&h,NULL,func,&arg) · pthread_join(h,NULL) · mutex lock/unlock alrededor de lo compartido. Compilar: gcc p.c -o p -pthread
CLI rápido: gcc p.c -o p./p · man 2 fork · ls -l · cat f · cp a b · mv a b · rm -r d · mkdir d · grep "x" f · ps aux | grep p · kill -9 PID · chmod +x f · redirección > añade >> · tubería |

📄 TEST — hechos que caen (del test real)

🧘 Antes de entrar: respira. Empieza por lo que domines (planificación y memoria son mecánicos). Gantt SIEMPRE en papel. Verifica esperas con el doble método. Si un resultado te parece imposible (espera mayor que todo lo que hay delante), repásalo. ¡Y justifica TODO! Suerte 🍀