Sincronización de hilos en Python mediante el método join

En entornos de programación concurrente, cuando múltiples hilos de ejecución acceden y modifican simultáneamente una varible global, pueden producirse inconsistencias en los datos conocidas como condiciones de carrera. Para mitigar este problema y garantizar la integridad de la información, es fundamental implementar mecansimos de sincronización.

Concepto de sincronización de hilos

La sincronización asegura que, en un instante dado, solo un hilo tenga permiso para manipular un recurso compartido. Es crucial comprender que en este contexto "sincronización" no significa que los hilos se ejecuten al mismo tiempo, sino que coordinan su orden de ejecución según una secuencia predefinida para mantener la coherencia de los datos.

Implementación del método join()

Una de las estrategias más directas para lograr esta coordinación en Python es utilizando el método join(). Este método obliga al hilo que lo invoca (generalmente el hilo principal) a bloquear su ejecución y esperar a que el hilo secundario especificado finalice por completo antes de continuar con las siguientes instrucciones.

A continuación, se presenta un ejemplo refactorizado donde dos hilos realizan operaciones de incremento sobre un contador global. Al aplicar join(), forzamos la ejecución secuencial de las tareas, evitando la pérdida de actualizaciones que ocurriría si ambos hilos modificaran la variable de forma verdaderamente simultánea.

import threading

# Variable global que será compartida y modificada por los hilos
contador_global = 0
ITERACIONES_POR_TAREA = 500000

def ejecutar_incrementos(identificador_tarea):
    global contador_global
    for _ in range(ITERACIONES_POR_TAREA):
        contador_global += 1
    print(f"Tarea {identificador_tarea} finalizada. Contador parcial: {contador_global}")

if __name__ == "__main__":
    # Instanciación de los hilos secundarios pasando argumentos dinámicos
    tarea_a = threading.Thread(target=ejecutar_incrementos, args=("A",))
    tarea_b = threading.Thread(target=ejecutar_incrementos, args=("B",))

    # Inicio y sincronización del primer hilo
    tarea_a.start()
    tarea_a.join()  # El hilo principal espera a que 'tarea_a' termine completamente

    # Inicio y sincronización del segundo hilo
    tarea_b.start()
    tarea_b.join()  # El hilo principal espera a que 'tarea_b' termine completamente

    print(f"Valor final consolidado del contador global: {contador_global}")

Resultado de la ejecución

Tarea A finalizada. Contador parcial: 500000
Tarea B finalizada. Contador parcial: 1000000
Valor final consolidado del contador global: 1000000

Etiquetas: Python Multithreading thread-synchronization join-method race-condition

Publicado el 7-14 21:01