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
:
-
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 argumentostarget
,args
ykwargs
permiten especificar la función a ejecutar en el hilo y sus argumentos.
-
start()
:- Este método se utiliza para iniciar la ejecución de un hilo. Llama al método
run()
de la claseThread
para ejecutar la función especificada.
- Este método se utiliza para iniciar la ejecución de un hilo. Llama al método
-
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 deThread
.
- Este es el método que se ejecuta cuando se inicia un hilo. Por defecto, llama a la función especificada en el argumento
-
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.
- Este método espera a que el hilo termine de ejecutarse. Si se especifica un
-
is_alive()
:- Este método devuelve
True
si el hilo está actualmente activo (es decir, si se está ejecutando) yFalse
si ya ha terminado.
- Este método devuelve
-
getName()
ysetName(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.
-
daemon
:- Este es un atributo que puede ser
True
oFalse
. Si se establece aTrue
, el hilo será un hilo daemon o de fondo, lo que significa que finalizará cuando el programa principal termine. Si se establece aFalse
(el valor predeterminado), el hilo se ejecutará de forma independiente y deberá terminar por sí solo.
- Este es un atributo que puede ser
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óntarea()
. - 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óntarea()
, el programa principal se detiene en la línea que llama ajoin()
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óntarea()
. - Antes de iniciar el hilo, establecemos el atributo
daemon
del hilo enTrue
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.