Todo el mundo ha oído hablar de los threads, pero ¿Cómo conseguir threads en python? Hoy espero poder explicártelo. Antes de nada, los threads (o hilos) son básicamente flujos de ejecución. Cada uno de estos flujos de ejecución corre independientemente de los demás, así que si quieres realizar entrada/salida de disco (o cualquier otra operación que consuma tiempo) y a la vez algo de cómputo, los threads son lo que buscas.
En lo tocante a python, hay una pequeña nota acerca de los threads a tener en cuenta. Los threads en python son simulados, es decir, si tienes 3 threads, realmente sólo existe uno, pero ése (el intérprete python) intercambia la ejecución de tus 3 threads de una manera planificada para simular el comportamiento de los threads. Por lo tanto, los threads de python se comportan como threads normales pero no son threads normales.
Vamos a ver un ejemplo simple…
from threading import Thread import time import random threads = 10 class MyThread (Thread): def __init__ (self, id): Thread.__init__ (self) self.TID = id # Thread id def run (self): print 'Thread [%d] starts' % self.TID time.sleep (random.random ()) # Some long call between 0 and 1 print 'Thread [%d] ends' % self.TID self.status = random.randrange (10) if __name__ == '__main__': s = time.time () threadBag = [] for id in range (threads): t = MyThread (id) t.start () threadBag.append (t) for thread in threadBag: thread.join () print 'Thread [%d] returned %d' % (thread.TID, thread.status) print 'Total time = %f' % (time.time () - s)
Este es un primer ejemplo sencillo utilizando threads en python. Cada thread es una instancia de una clase derivada de threading.Thread. Puedes ver que MyThread es esa clase. El método de ejecución es run (self) que es invocado desde la clase base. Debes poner todo el código del thread dentro de este método para ejecutarlo. El thread terminará al retorno de ese método. El otro método utilizado es __init__. Si necesitas pasar datos al thread, éste es tu métdo. Almacena todos los datos en variables de instancia (atributos) y disfruta! Para devolver un valor desde el thread, utiliza self.status y recupéralo cuando hagas el join () del thread.
El ejemplo sencillo crea algunos threads, los lanza (con el método start()) y después los reúne para recuperar su estado de salida. También calcula el tiempo necesario para todo el script. La salida (variable, debido al uso del módulo random) es:
Thread [0] starts Thread [1] starts Thread [2] starts Thread [3] starts Thread [4] starts Thread [5] starts Thread [6] starts Thread [7] starts Thread [8] starts Thread [9] starts Thread [0] ends Thread [0] returned 2 Thread [3] ends Thread [5] ends Thread [1] ends Thread [1] returned 7 Thread [6] ends Thread [9] ends Thread [4] ends Thread [7] ends Thread [2] ends Thread [2] returned 2 Thread [3] returned 2 Thread [4] returned 5 Thread [5] returned 3 Thread [6] returned 2 Thread [7] returned 5 Thread [8] ends Thread [8] returned 2 Thread [9] returned 6 Total time = 0.861000
Fíjate en los ‘ends’ de los threads, ya que la creación y reunión de los threads son bucles secuenciales, por lo que siempre saldrán en orden. Puedes ver que los threads necesitan diferentes tiempos para terminar. Pero la magía consiste en que el tiempo total de todo el script es, más o menos, el máximo de los tiempos aleatorios, así que ¡La ejecución es paralela!!!
Para más información sobre threads, visita este link.
Por ahora es todo. Cualquier comentario es bienvenido.