Unidad 3: Profundización

El Baile de los Procesos

En los sistemas modernos, los procesos no son islas. A menudo necesitan cooperar para lograr un objetivo común. Un servidor web, por ejemplo, puede tener un proceso que acepta conexiones y otro que consulta la base de datos. Para que esto funcione, deben comunicarse (el primer proceso le pasa la petición al segundo) y sincronizarse (el primer proceso debe esperar la respuesta del segundo antes de contestar al usuario).

Esta cooperación, sin embargo, abre la puerta a problemas complejos y sutiles que son de los más difíciles de depurar en programación.

Problema 1: Condición de Carrera (Race Condition)

Una condición de carrera es el problema más común de la concurrencia. Ocurre cuando el resultado de una operación depende del orden impredecible en que la CPU ejecuta las instrucciones de dos o más procesos que acceden a un recurso compartido.

Ejemplo: El Saldo Bancario

Imagina dos procesos (P1 y P2) que intentan retirar $100 de una cuenta que tiene $500.

Saldo inicial: $500

// Secuencia IDEAL
1. P1 lee Saldo ($500).
2. P1 calcula nuevo saldo ($400).
3. P1 escribe nuevo saldo ($400).
4. P2 lee Saldo ($400).
5. P2 calcula nuevo saldo ($300).
6. P2 escribe nuevo saldo ($300).
Resultado final correcto: $300

// Secuencia de CARRERA (una de muchas posibles)
1. P1 lee Saldo ($500).
2. (El SO cambia la CPU a P2)
3. P2 lee Saldo ($500).
4. P2 calcula nuevo saldo ($400).
5. P2 escribe nuevo saldo ($400).
6. (El SO vuelve a P1)
7. P1 calcula su nuevo saldo (basado en el $500 que leyó) -> $400.
8. P1 escribe nuevo saldo ($400).
Resultado final INCORRECTO: $400. ¡El banco perdió $100!
                    

La zona del código donde se accede al recurso compartido (el saldo) se llama Sección Crítica. La solución es asegurar que solo un proceso pueda estar en su sección crítica a la vez. Esto se llama exclusión mutua.

Problema 2: El Abrazo Mortal (Deadlock)

Un deadlock es una situación en la que dos o más procesos quedan permanentemente bloqueados, esperando cada uno un recurso que tiene el otro.

Analogía: El Puente de un Solo Carril

Imagina un puente estrecho donde solo cabe un coche. Al mismo tiempo, un coche entra por el extremo A y otro por el extremo B. Llegan al medio y se encuentran frente a frente.

  • El coche A necesita el espacio que ocupa el coche B para avanzar (Pide Recurso).
  • El coche B necesita el espacio que ocupa el coche A para avanzar (Pide Recurso).
  • Ninguno de los dos está dispuesto a retroceder y ceder su espacio (No ceden su Recurso).

El resultado es un bloqueo eterno. Ambos coches (procesos) están en un deadlock.

Soluciones: Mecanismos del SO

Para evitar estos problemas, los sistemas operativos ofrecen herramientas (mecanismos) a los programadores.

Mecanismos de Comunicación

Memoria Compartida: Es como si dos oficinistas compartieran una misma pizarra. Es muy rápido porque ambos ven los cambios al instante. El problema es que si ambos intentan escribir en el mismo lugar a la vez, se genera un caos. Requiere de mecanismos de sincronización adicionales (como un "turno para escribir") para funcionar bien.

Paso de Mensajes: Es como si los oficinistas se enviaran notas por correo interno. Es más lento, pero más seguro y simple. No hay riesgo de que escriban en el mismo lugar. El SO actúa como el cartero, asegurando que los mensajes lleguen de forma ordenada.

Mecanismos de Sincronización

Mutex (Exclusión Mutua): Es la herramienta más simple para proteger una sección crítica. Un mutex es como la llave de un baño público. Solo una persona (proceso) puede tener la llave y entrar al baño (sección crítica) a la vez. Cuando sale, deja la llave para que otro pueda entrar. Garantiza exclusión mutua.

Semáforo: Es una versión más general. Es como un mostrador que presta un número limitado de llaves, digamos, 5 llaves para usar 5 bicicletas de un parque. Los primeros 5 procesos pueden tomar una llave y usar una bicicleta. El sexto que llegue deberá esperar a que alguien devuelva una. Un mutex es simplemente un semáforo con una sola llave (valor 1).

Preguntas para el Debate

  • Si la "memoria compartida" es más rápida, ¿por qué alguien usaría el "paso de mensajes"?
  • ¿Puedes pensar en un ejemplo de la vida real (diferente a los mencionados) que represente un deadlock?
  • ¿Qué crees que es más difícil para un programador: evitar una condición de carrera o evitar un deadlock? ¿Por qué?

Desafío: Desbloquea las Respuestas

¿Cuál es el nombre del mecanismo de sincronización que actúa como una "llave única" para una sección crítica, garantizando la exclusión mutua?