Operaciones Atómicas y Secciones Críticas en Programación Concurrente

Clasificado en Informática

Escrito el en español con un tamaño de 3,79 KB

¿Qué es una Operación Atómica?

Una operación atómica es aquella que se ejecuta como una unidad indivisible, es decir, de forma completa e ininterrumpida. Esto significa que, una vez iniciada, ningún otro proceso o hilo puede leer o modificar los datos involucrados hasta que la operación haya finalizado por completo. Es como si se realizara en un único paso instantáneo.

Atomicidad en Sistemas Monoprocesador y Multiprocesador

En un sistema con un único procesador, una operación es inherentemente atómica si se ejecuta con una sola instrucción de la CPU. Sin embargo, si la operación requiere múltiples instrucciones, puede ser interrumpida por un cambio de contexto, perdiendo así su atomicidad. Operaciones comunes que parecen simples, como las escrituras en memoria o un incremento (a++), a menudo no son atómicas, ya que internamente involucran varios pasos: lectura, modificación y escritura.

En sistemas multiprocesador, donde múltiples hilos de un mismo proceso se ejecutan simultáneamente, garantizar la atomicidad es aún más complejo. Varios hilos podrían intentar modificar los mismos datos al mismo tiempo, generando inconsistencias y condiciones de carrera. Una técnica para mejorar la visibilidad de los cambios entre hilos es declarar las variables como volatile. Esta declaración asegura que las lecturas y escrituras se realicen directamente en la memoria principal, pero no garantiza la atomicidad de operaciones compuestas. Para asegurar la atomicidad en bloques de código más complejos, se recurre al concepto de sección crítica.

La Sección Crítica: Protegiendo Recursos Compartidos

Se denomina sección crítica a la porción de código que accede a recursos compartidos (variables, estructuras de datos, archivos, etc.) y que no debe ser ejecutada por más de un hilo o proceso a la vez. Este concepto es fundamental tanto para hilos como para procesos concurrentes, siempre que compartan dichos recursos.

Cuando un hilo o proceso entra en su sección crítica, ningún otro puede acceder a la suya, lo que permite ordenar el acceso concurrente y evitar errores. Esto implica dos cosas:

  • Si otro hilo intenta ejecutar su sección crítica, se bloqueará hasta que el que la está ocupando finalice.
  • Se establece una relación de orden (antes-después) en la ejecución, garantizando que los cambios en los datos sean visibles para todos los hilos de manera consistente.

Requisitos para una Solución Válida

Toda solución al problema de la sección crítica debe cumplir tres requisitos fundamentales:

  • Exclusión mutua: Es la característica principal. Si un proceso está ejecutando su sección crítica, ningún otro puede ejecutar la suya al mismo tiempo.
  • Progreso: Si no hay ningún proceso en su sección crítica y existen procesos que desean entrar, la selección del siguiente no puede posponerse indefinidamente. Solo los procesos que están listos para entrar pueden participar en esta decisión.
  • Espera limitada (Bounded Waiting): Debe existir un límite en el número de veces que a otros procesos se les permite entrar en sus secciones críticas después de que un proceso haya solicitado el acceso y antes de que se le conceda. Esto previene la inanición (starvation) de un proceso.

Implementación en la Práctica

Para implementar estas soluciones, lenguajes de programación modernos como Java proporcionan mecanismos de sincronización de alto nivel, entre los que destacan los semáforos y los monitores.

Entradas relacionadas: