Ir al contenido

Deadlock: condiciones, prevención, evitación y detección

🎯 Al terminar podrás

  1. Enunciar las 4 condiciones de Coffman y decir cuáles son de política y cuál convierte la posibilidad en deadlock.
  2. Para una solución dada (orden de locks, portero, trylock…), decir qué condición rompe.
  3. Aplicar el banquero: calcular Need = C − A, encontrar una secuencia segura y decidir si se concede una petición.
  4. Distinguir prevención, evitación y detección, y elegir una según el escenario.

Antes necesitas: Semáforos y productor–consumidor

  • Visual mira el diagrama o la tabla y explica qué cambia en cada paso
  • Simulador predice el estado antes de pulsar el paso siguiente
  • Debate elige una alternativa para el escenario y defiéndela

Deadlock: bloqueo permanente de un conjunto de procesos que compiten por recursos o se comunican. Cada uno espera un evento que solo puede producir otro proceso bloqueado del mismo conjunto. No hay una solución eficiente en el caso general.

Ejemplo del tráfico (fig. 6.1): cuatro autos llegan a un cruce de cuatro altos y cada uno necesita dos cuadrantes (a-b, b-c, c-d, d-a).

  • Si todos respetan la regla «cede al de tu derecha», nadie avanza. Es un deadlock potencial: si uno decide pasar, se resuelve.
  • Si todos entran a la vez, cada uno ocupa un cuadrante y espera el siguiente. Es un deadlock real.

Región fatal (diagrama de progreso conjunto, fig. 6.2)

Sección titulada «Región fatal (diagrama de progreso conjunto, fig. 6.2)»

P hace get A … get B … release A … release B y Q hace get B … get A … release B … release A. Si el camino de ejecución entra a la región fatal (P tiene A y Q tiene B), el deadlock es inevitable. Si P liberara A antes de pedir B (fig. 6.3), no existiría región fatal, sin importar el orden de ejecución. El deadlock depende de la lógica y de la dinámica.

ReutilizablesConsumibles
los usa un proceso a la vez y no se agotanse crean y se destruyen al consumirse
CPU, canales de E/S, memoria, dispositivos, archivos, bases de datos, semáforosinterrupciones, señales, mensajes, datos en buffers de E/S
Ejemplo: P pide el disco D y luego la cinta T; Q pide T y luego D. Con el orden p0 p1 q0 q1 p2 q2 hay deadlock. Otro: hay 200 KB, P1 pide 80 y luego 60, P2 pide 70 y luego 80Ejemplo: P1 hace Receive(P2); Send(P2) y P2 hace Receive(P1); Send(P1) con receive bloqueante. Puede estar años sin manifestarse

Grafo de asignación de recursos (Holt): una arista proceso → recurso es una petición pendiente; una arista recurso → proceso es una asignación. Cada punto dentro de un recurso es una instancia. Un ciclo con recursos de una sola instancia implica deadlock. Con varias instancias, un ciclo no garantiza deadlock (fig. 6.5d).

#CondiciónSignificado
1Exclusión mutuaun recurso solo lo usa un proceso a la vez
2Hold and waitse retienen recursos mientras se esperan otros
3No preemptionno se le puede quitar un recurso a quien lo tiene
4Espera circularhay una cadena cerrada en que cada proceso espera un recurso del siguiente

Las condiciones 1–3 son de política: necesarias pero no suficientes (hacen posible el deadlock). Con la 4, que es una consecuencia de la dinámica, las cuatro juntas son suficientes: el deadlock existe, porque se entró a la región fatal. Las condiciones 1–3 suelen ser deseables: la exclusión mutua da consistencia, y la preemption de datos exige rollback.

CondiciónCómo se previeneCosto
Exclusión mutuaen general no se puede (hay recursos intrínsecamente exclusivos)—
Hold and waitpedir todos los recursos de una vez, y bloquear hasta obtenerlos todosesperas largas, recursos ociosos, hay que saber de antemano qué se necesita (difícil con módulos o hilos)
No preemptionsi se deniega una petición, soltar todo y volver a pedir; o que el SO expropie al otro (si las prioridades son distintas)solo sirve para recursos cuyo estado se guarda fácil, como la CPU
Espera circularorden lineal de los tipos de recurso: solo se pide Rj si j > i para todo Ri que ya se tieneineficiente; imposible tener Ri → Rj → Ri

El caso más simple, de clase (deadlokck_single_core.c): un solo hilo hace pthread_mutex_lock(&mtx) dos veces seguidas sobre un mutex por defecto (NORMAL) y se bloquea contra sí mismo: es un auto-deadlock, que no necesita un segundo hilo. Con un mutex RECURSIVE no pasaría; con uno ERRORCHECK, el segundo lock devolvería EDEADLK.

pthread_mutex_trylock rompe el hold and wait («si no consigo el segundo, suelto el primero»), así que evita el deadlock, pero puede producir livelock o starvation (E1 2024-II).

2) Evitación: decidir dinámicamente, con información del futuro

Sección titulada «2) Evitación: decidir dinámicamente, con información del futuro»

Permite las condiciones 1–3, pero nunca entra a un estado del que no pueda garantizar la salida. Da más concurrencia que la prevención, pero exige conocer los máximos de antemano.

Notación: los vectores Resource R y Available V, y las matrices Claim C (máximos declarados) y Allocation A.

  • Rj=Vj+∑iAijR_j = V_j + \sum_i A_{ij} (cada recurso está disponible o asignado);

  • Cij≤RjC_{ij} \le R_j (nadie reclama más de lo que existe);

  • Aij≤CijA_{ij} \le C_{ij} (nadie tiene más de lo que reclamó).

  • Denegar el inicio de un proceso: iniciar Pn+1P_{n+1} solo si Rj≥C(n+1)j+∑i=1nCijR_j \ge C_{(n+1)j} + \sum_{i=1}^{n} C_{ij} para todo j. Es muy conservador: supone que todos pedirán su máximo a la vez.

  • Denegar asignaciones (algoritmo del banquero, Dijkstra 1965): se simula la asignación y se concede solo si el nuevo estado es seguro. Un estado seguro es uno desde el que existe al menos una secuencia en que todos terminan; en cada paso se busca un PkP_k con Ck−Ak≤C_k - A_k \le disponible, se simula que termina y se suman sus AkA_k.

Algoritmo del banquero (prueba de seguridad)

Las matrices son editables. Avanza paso a paso: en verde los procesos que pueden terminar (se marcan) y en ámbar el elegido en cada paso.

Resource R(9,3,6)
Available V = R − ΣA(0,1,1)
currentavail (paso 0)(0,1,1)
Claim C (máximo declarado)
R1R2R3
P1
P2
P3
P4
Allocation A
R1R2R3
P1
P2
P3
P4
Need = C − A
P1: (2,2,2)P2: (0,0,1)P3: (1,0,3)P4: (4,2,0)
currentavail = Available = (0,1,1)
V = (0,1,1). Solo P2 puede terminar (le falta (0,0,1)); al liberar, todos los demás pueden. Secuencia segura: P2, P1, P3, P4.

Peldaño 1 · Resueltolee cada paso y su porqué

Resuelto: la fig. 6.7a en el simulador

Elige el preset «Fig. 6.7a» y avanza paso a paso. Antes de cada paso, di qué proceso puede terminar y con qué disponible queda. Resultado (verificado con un script): V = (0, 1, 1); Need de P2 = (0, 0, 1) ≤ V, así que P2 termina y V = (6, 2, 3). Luego P1 (V = 7 2 3), P3 (9 3 4) y P4 (9 3 6). El estado es seguro. La escalera completa del banquero, con la notación de la clase, está en la clase de teoría sem. 11.

Restricciones del banquero:

  • los máximos se declaran por adelantado;
  • los procesos deben ser independientes, sin restricciones de sincronización entre ellos;
  • el número de recursos es fijo;
  • nadie termina mientras tenga recursos.

Se conceden los recursos siempre que se pueda y periódicamente se busca el ciclo. Revisar en cada petición detecta temprano y el algoritmo es incremental, pero consume CPU.

Algoritmo (Coffman 1971), con Allocation, Available y la matriz de peticiones Q:

  1. Marcar a los procesos con una fila de Allocation en ceros.
  2. W = Available.
  3. Buscar un proceso no marcado con Qi≤WQ_i \le W. Si no hay, terminar.
  4. Marcarlo, hacer W += A_i y volver al paso 3.

Hay deadlock si y solo si quedan procesos sin marcar, y esos son exactamente los que están en deadlock. El simulador de arriba incluye el ejemplo de la fig. 6.10.

Recuperación, de menor a mayor sofisticación:

  1. Abortar a todos los procesos en deadlock. Es lo más común.
  2. Volver cada uno a un checkpoint y reiniciar. El deadlock podría repetirse, pero el no determinismo suele evitarlo.
  3. Abortar uno por uno hasta que se rompa el ciclo, volviendo a correr la detección tras cada aborto.
  4. Expropiar recursos uno por uno, haciendo rollback del proceso afectado.

Para 3 y 4 se elige primero al proceso con menos CPU consumida, menos salida producida, más tiempo restante estimado, menos recursos o menor prioridad.

Agrupar los recursos en clases ordenadas: espacio de swap, luego recursos de proceso, luego memoria principal, luego recursos internos. Se usa un orden lineal entre clases, y dentro de cada clase la estrategia que mejor le sirve:

ClaseEstrategia
Espacio de swapprevención: pedir todo de una vez (los máximos suelen conocerse) o evitación
Recursos de proceso (cintas, archivos)evitación (se declaran de antemano) u orden dentro de la clase
Memoria principalprevención por expropiación: swap out del proceso
Recursos internos (canales de E/S)orden lineal

Cinco filósofos, cinco tenedores y hacen falta dos para comer. Se busca exclusión mutua sobre cada tenedor, sin deadlock y sin starvation (en este caso, literal).

Simulador de semáforos

Haz clic en un proceso para ejecutar su siguiente instrucción. Semántica de Stallings: el valor puede ser negativo (|valor| = procesos en cola) y la cola es FIFO.

fork[0]1
fork[1]1
fork[2]1
fork[3]1
fork[4]1
Registro vacío.
Haz que cada filósofo tome su tenedor izquierdo (un clic en F0…F4): los 5 quedan bloqueados esperando el derecho. Es DEADLOCK por espera circular.
Solución¿Deadlock?Idea
Cada uno toma el izquierdo y luego el derecho (fig. 6.12)Sílos 5 toman el izquierdo a la vez: espera circular
Portero room = 4 (fig. 6.13)Nocon 4 sentados y 5 tenedores, alguno tiene los dos
Monitor con ForkReady[5] (fig. 6.14)Notoma izquierdo y derecho dentro del monitor: nadie se cuela entre medio
Asimetría: el último toma primero el derechoNorompe el orden circular (es prevención por orden lineal de tenedores)
Tomar ambos o ninguno (verificar los dos con el lock)Norompe el hold and wait
MecanismoPara quéDetalle
Pipesdatos productor–consumidorbuffer circular FIFO. Sin nombre (entre parientes) o con nombre (FIFO). El SO hace la exclusión mutua; si el pipe está lleno, el escritor se bloquea
Mensajesdatoscolas de mensajes (msgsnd, msgrcv) con un tipo; se puede recibir FIFO o por tipo
Memoria compartidadatos (lo más rápido)los procesos se sincronizan por su cuenta
Semáforosdisparar accionesvienen en conjuntos. semop aplica una lista de operaciones: sem_op > 0 suma; == 0 espera a que valga 0; < 0 resta o espera
Señalesdisparar accionessin prioridades y no se encolan (un bit por tipo); se procesan al despertar o al volver de una syscall. Las señales RT de Linux sí se encolan, tienen prioridad y llevan un valor

Autoevaluación

0/9 correctas · 0 respondidas
1. ¿Qué condición de Coffman es la que convierte la POSIBILIDAD de deadlock en EXISTENCIA?
2. Pedir todos los recursos de una vez previene…
3. Ordenar los tipos de recurso y pedirlos siempre en orden creciente previene…
4. Un estado inseguro…
5. Los mensajes y las señales son recursos…
6. Con varias instancias por recurso, un ciclo en el grafo de asignación…
7. La recuperación más común en los SO reales es…
8. Filósofos con room = 4: ¿por qué no hay deadlock?
9. Exigencia del banquero:

📈 ¿Qué tan bien lo dominas?

Elige pensando en lo que hiciste, no en lo que leíste. Para marcar 3 tienes que haber resuelto un ejercicio nuevo sin pistas y haberlo justificado. Si solo lo leíste y sientes que «ya entendí», todavía es un 1.

Fuente ·Stallings 9e cap. 6 (§6.1–6.7, figs. 6.1–6.14, tabla 6.1) · for_partial/E1_OS_2024_II__Solucionario_.pdf (P4: condiciones y trylock) · for_partial/E1_OS_2024_I__Respuestas_.pdf (P5) · código del curso so/deadlokck_single_core.c