Bienvenidos un día más al curso de Python. En este capítulo vamos a continuar con la ejecución de hilos, para poder realizar tareas simultáneas en nuestras aplicaciones. Para ello, vamos a mostraros cómo podemos hacer que los hilos se ejecuten por un tiempo determinado, y cómo podemos finalizar su ejecución de una manera correcta. Así que pongámonos manos a la obra.
Hilos que funcionan durante un tiempo
En ocasiones nos puede interesar que los hilos se ejecuten por un tiempo determinado. En el ejemplo que os vamos a mostrar a continuación, hemos iniciado 5 hilos que funcionarán durante un segundo. La tarea de cada hilo consiste en incrementar un contador hasta que se alcance el tiempo límite de ejecución. Se ha utilizado el módulo «time» para obtener el momento inicial y calcular el tiempo límite de ejecución.
Cuando finaliza el tiempo de cada hilo, el valor máximo contado se va añadiendo a un diccionario que se muestra cuando el último hilo activo está finalizando.
Para conocer cuándo está finalizando el último hilo, utilizaremos la función “threading.active_count()” la cual nos devuelve el número de hilos que aún quedan activos, incluyendo el hilo principal (que se corresponde con el hilo que inicia el propio programa), es decir, cuando el último hilo “Thread” esté terminando quedarán activos 2 hilos.
Por último se mostrará al final una lista con la información de estos hilos, esta información ha sido obtenida a través de la función “threading.enumerate()”.
Comentaros también que la variable “vmax_hilos” contiene los valores máximos del contador de cada hilo. Esta variable se inicializa al comienzo del programa y se declara después como global dentro de la función. Esto se hace para lograr mantener «vivos» los valores máximos que se añaden al diccionario al concluir cada hilo. Si no se declara como global sólo permanecerá el último valor agregado.
import threading, time
vmax_hilos = {}
def contar(segundos):
"""Contar hasta un límite de tiempo"""
global vmax_hilos
contador = 0
inicial = time.time()
limite = inicial + segundos
nombre = threading.current_thread().getName()
while inicial <= limite:
contador += 1
inicial = time.time()
print(nombre, contador)
vmax_hilos[nombre] = contador
if threading.active_count() == 2:
print(vmax_hilos)
print(threading.enumerate())
segundos = 1
for num_hilo in range(5):
hilo = threading.Thread(name='hilo%s' % num_hilo,
target=contar,
args=(segundos,))
hilo.start()
Demonios
Tenemos dos métodos diferentes para finalizar un programa basado en hilos correctamente. En el primer método, el hilo principal del programa espera a que todos los hilos creados con “Thread” terminen su trabajo. Este es el caso de todos los ejemplos mostrados hasta el momento.
En el segundo método, el hilo principal del programa puede finalizar aunque uno o más hilos hijos no hayan terminado su tarea. Teniendo en cuenta que cuando finalice el hilo principal también lo harán estos hilos especiales llamados “demonios”. Si existen hilos no-demonios el hilo principal esperará a que éstos concluyan su trabajo. Los demonios son útiles para programas que realizan operaciones de monitorización o de chequeo de recursos, servicios, aplicaciones, etc.
Para