Introduction to RTOS Part 10 - Deadlock and Starvation | Digi-Key Electronics
¿Cuál es el problema de los filósofos comensales?
Introducción al Problema
- Cinco filósofos entran a un restaurante y se sientan en una mesa redonda, donde cada uno tiene un solo palillo entre ellos.
- Cada filósofo necesita dos palillos para comer, lo que plantea el desafío de crear un algoritmo que garantice que todos tengan tiempo para comer.
Importancia del Problema
- Este problema es una analogía para múltiples hilos con múltiples bloqueos intentando acceder a un recurso compartido.
- Se abordarán dos problemas importantes: la inanición (starvation) y el bloqueo (deadlock), que pueden causar serios problemas en programas multihilo.
Inanición y Bloqueo: Definiciones y Soluciones
Inanición
- En la analogía, algunos filósofos (hilos de alta prioridad) pueden monopolizar los palillos, dejando a otros sin acceso. Esto se conoce como inanición.
- Para prevenir la inanición, se sugiere introducir retrasos o ceder el control al programador para permitir que otros hilos se ejecuten.
Técnicas para Prevenir Inanición
- En sistemas multicore, las tareas de alta prioridad pueden ejecutarse en núcleos diferentes o activarse mediante interrupciones.
- La técnica de envejecimiento (aging) permite aumentar gradualmente la prioridad de las tareas en espera, asegurando que eventualmente obtengan tiempo de CPU.
Bloqueo: Un Problema Crítico
Algoritmo Simple y sus Consecuencias
- Un algoritmo simple donde cada filósofo toma primero su palillo izquierdo puede llevar a un estado de bloqueo si todos intentan hacerlo simultáneamente.
- El bloqueo ocurre cuando todos los filósofos sostienen su palillo izquierdo pero no pueden tomar el derecho, quedando atrapados sin poder comer.
Prevención del Bloqueo
- Se presentan técnicas consideradas mejores prácticas en programación concurrente para evitar bloqueos.
Prevención de Deadlocks en Sistemas Concurrentes
Introducción a los Deadlocks
- Se explica cómo el uso de múltiples mutexes y semáforos puede llevar fácilmente a un deadlock, donde ninguna tarea puede continuar.
- Para prevenir o detectar deadlocks, es crucial no permitir que una tarea se bloquee indefinidamente al esperar un mutex o semáforo. Se sugiere implementar un tiempo de espera (timeout).
Implementación de Timeouts
- Al establecer un timeout de 1 segundo para la adquisición de mutexes, si una tarea excede este tiempo, imprime un mensaje de error y libera cualquier mutex adquirido.
- Aunque los timeouts ayudan a evitar deadlocks totales, pueden dar lugar a otro problema conocido como "live lock", donde las tareas no están bloqueadas pero tampoco pueden avanzar.
Soluciones Propuestas para Deadlocks y Live Locks
- Se presentan soluciones para abordar los problemas de deadlock y live lock. Una solución implica asignar una jerarquía o prioridad a los recursos compartidos (chopsticks).
- En esta solución, cada filósofo comienza tomando el chopstick con el número más bajo. Esto evita que todos intenten tomar el mismo recurso simultáneamente.
Ejemplo Práctico con Mutexes
- La implementación del algoritmo muestra que solo uno de los chopsticks queda disponible en la mesa, permitiendo que otros filósofos continúen comiendo sin entrar en deadlock.
- Es importante liberar los mutexes en orden inverso al que fueron adquiridos como buena práctica, aunque no afecta directamente al algoritmo.
Introducción del Arbitraje
- Otra solución es introducir un "arbitro" que determine quién puede acceder a los recursos compartidos. Este arbitro actúa como un mutex adicional.
- El arbitro permite que solo una tarea acceda a ambos chopsticks a la vez, lo cual previene el deadlock pero limita la ejecución paralela.
Desafío Final: Filósofos Comensales
- Se presenta el desafío completo del problema de los filósofos comensales utilizando cinco tareas en lugar de dos. Cada filósofo intenta tomar sus chopsticks y comer.