Skip to main content

Threads

Un hilo (o thread en inglés) en Python es una forma de ejecutar código de manera concurrente. En otras palabras, un hilo permite que una parte del programa se ejecute de forma independiente al mismo tiempo que otras partes. Esto puede ser útil para tareas que se pueden realizar en paralelo, como manejar varias conexiones de red, procesar datos de archivos, o realizar cálculos intensivos en segundo plano mientras el programa principal continúa ejecutándose.

En Python, se puede crear un hilo utilizando la biblioteca estándar threading. Se define una función que se desea ejecutar en el hilo, y luego se crea un objeto Thread que toma esa función como argumento y se inicia.

Por ejemplo:

import threading

def mi_funcion():
print("Hilo ejecutándose")

# Crear un hilo
mi_hilo = threading.Thread(target=mi_funcion)

# Iniciar el hilo
mi_hilo.start()

En este ejemplo, la función mi_funcion() se ejecutará de forma independiente en el nuevo hilo creado por threading.Thread.

Funciones de los threads

En Python, la biblioteca estándar threading proporciona herramientas para trabajar con hilos (o threads). A continuación se describen las principales funciones y métodos que se utilizan para trabajar con hilos en threading:

  1. threading.Thread:

    • Thread(target=None, args=(), kwargs={}, *, daemon=None): Esta es la clase que representa un hilo. Se utiliza para crear un hilo nuevo. Los argumentos target, args y kwargs permiten especificar la función a ejecutar en el hilo y sus argumentos.
  2. start():

    • Este método se utiliza para iniciar la ejecución de un hilo. Llama al método run() de la clase Thread para ejecutar la función especificada.
  3. run():

    • Este es el método que se ejecuta cuando se inicia un hilo. Por defecto, llama a la función especificada en el argumento target cuando se crea el hilo. Puedes sobrescribir este método si estás creando una subclase de Thread.
  4. join(timeout=None):

    • Este método espera a que el hilo termine de ejecutarse. Si se especifica un timeout, esperará por ese tiempo antes de continuar.
  5. is_alive():

    • Este método devuelve True si el hilo está actualmente activo (es decir, si se está ejecutando) y False si ya ha terminado.
  6. getName() y setName(name):

    • Estos métodos permiten obtener y establecer el nombre de un hilo, respectivamente. Esto puede ser útil para identificar hilos si se tienen múltiples hilos ejecutándose.
  7. daemon:

    • Este es un atributo que puede ser True o False. Si se establece a True, el hilo será un hilo daemon o de fondo, lo que significa que finalizará cuando el programa principal termine. Si se establece a False (el valor predeterminado), el hilo se ejecutará de forma independiente y deberá terminar por sí solo.

Join

El método join() en la biblioteca threading de Python es utilizado para esperar a que un hilo termine su ejecución antes de continuar con la ejecución del programa. En otras palabras, cuando se llama a join() en un hilo, el programa se detiene en esa línea y espera a que el hilo termine de ejecutar la función asignada.

El método join() también puede tomar un argumento opcional timeout, que especifica la cantidad máxima de tiempo que el programa esperará a que el hilo termine. Si el hilo no ha terminado en ese tiempo, el programa continuará con su ejecución.

Veamos un ejemplo para ilustrar cómo se usa join():

import threading
import time

def tarea():
print("Hilo iniciando tarea...")
time.sleep(3) # Simula una tarea que toma 3 segundos
print("Hilo terminando tarea")

# Crear un hilo que ejecute la función 'tarea'
mi_hilo = threading.Thread(target=tarea)

# Iniciar el hilo
mi_hilo.start()

# Aquí llamamos a join() para esperar a que el hilo termine
print("Esperando a que el hilo termine...")
mi_hilo.join() # El programa esperará hasta que 'mi_hilo' termine

print("Hilo ha terminado, programa continúa.")

En este ejemplo:

  • Creamos un hilo (mi_hilo) que ejecutará la función tarea().
  • Iniciamos el hilo usando mi_hilo.start().
  • Luego, llamamos a mi_hilo.join() para esperar a que el hilo termine su ejecución.
  • Mientras mi_hilo está ejecutando la función tarea(), el programa principal se detiene en la línea que llama a join() y espera a que el hilo termine.
  • Una vez que el hilo ha terminado, el programa continúa con su ejecución y se imprime el mensaje "Hilo ha terminado, programa continúa".

El método join() es útil cuando quieres asegurarte de que todos los hilos se han completado antes de continuar con el resto de tu programa, o cuando quieres sincronizar la ejecución de múltiples hilos.

Daemon

En Python, un hilo daemon es un tipo especial de hilo que se ejecuta en segundo plano y termina automáticamente cuando el programa principal termina. Un hilo daemon no impide que el programa finalice, por lo que si todos los hilos en ejecución son daemon, el programa finalizará incluso si esos hilos aún no han completado su tarea.

Para convertir un hilo en un hilo daemon, puedes establecer su atributo daemon en True antes de iniciar el hilo. Por ejemplo:

import threading
import time

def tarea():
print("Hilo daemon iniciando tarea...")
time.sleep(5) # Simula una tarea que toma 5 segundos
print("Hilo daemon terminando tarea")

# Crear un hilo que ejecute la función 'tarea'
mi_hilo_daemon = threading.Thread(target=tarea)

# Establecer el hilo como daemon antes de iniciarlo
mi_hilo_daemon.daemon = True

# Iniciar el hilo
mi_hilo_daemon.start()

# El programa principal continúa su ejecución
print("Programa principal continúa ejecutándose...")

# Como el hilo es daemon, el programa finalizará cuando el programa principal termine

En este ejemplo:

  • Creamos un hilo (mi_hilo_daemon) que ejecutará la función tarea().
  • Antes de iniciar el hilo, establecemos el atributo daemon del hilo en True para convertirlo en un hilo daemon.
  • Iniciamos el hilo usando mi_hilo_daemon.start().
  • El hilo comienza a ejecutar la función tarea() y el programa principal continúa con su ejecución.
  • Dado que mi_hilo_daemon es un hilo daemon, no evitará que el programa principal termine, incluso si el hilo aún está ejecutando su tarea. Cuando el programa principal finalice, todos los hilos daemon también terminarán automáticamente.

Es importante tener en cuenta que los hilos daemon no son adecuados para todas las tareas. Si un hilo daemon está realizando una operación crítica o que debe completarse antes de finalizar el programa, es posible que quieras considerar usar hilos normales (no daemon) y manejar su finalización adecuadamente. Los hilos daemon son útiles para tareas que no necesitan completarse si el programa principal termina, como tareas de registro o de limpieza de recursos en segundo plano.