Hilo en python usando la cola

Quería usar hilos en Python para descargar gran cantidad de páginas web y revisé el siguiente código que usa colas en uno de los sitios web.

Se pone un bucle de tiempo infinito. ¿Cada uno de los hilos se ejecuta continuamente sin terminar hasta que todos están completos? Me estoy perdiendo de algo.

#!/usr/bin/env python import Queue import threading import urllib2 import time hosts = ["http://yahoo.com", "http://google.com", "http://amazon.com", "http://ibm.com", "http://apple.com"] queue = Queue.Queue() class ThreadUrl(threading.Thread): """Threaded Url Grab""" def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue def run(self): while True: #grabs host from queue host = self.queue.get() #grabs urls of hosts and prints first 1024 bytes of page url = urllib2.urlopen(host) print url.read(1024) #signals to queue job is done self.queue.task_done() start = time.time() def main(): #spawn a pool of threads, and pass them queue instance for i in range(5): t = ThreadUrl(queue) t.setDaemon(True) t.start() #populate queue with data for host in hosts: queue.put(host) #wait on the queue until everything has been processed queue.join() main() print "Elapsed Time: %s" % (time.time() - start) 

La configuración de los hilos para que sean hilos de daemon hace que se salgan cuando se termina el principal. Pero, sí, tienes razón en que tus hilos se ejecutarán continuamente mientras haya algo en la queue contrario se bloqueará.

La documentación explica este detalle.

La documentación de Python Threading también explica la parte del daemon .

El progtwig completo de Python se cierra cuando no quedan hilos vivos que no sean del demonio.

Por lo tanto, cuando la cola se vacía y la queue.join reanuda cuando el intérprete sale, los hilos morirán.

EDIT: corrección en el comportamiento predeterminado para la Queue

Su guión funciona bien para mí, así que asumo que está preguntando qué está pasando para que pueda entenderlo mejor. Sí, su subclase coloca cada hilo en un bucle infinito, esperando que algo se ponga en la cola. Cuando se encuentra algo, lo agarra y hace lo suyo. Luego, la parte crítica, notifica a la cola que se ha realizado con queue.task_done y reanuda la espera de otro elemento en la cola.

Mientras todo esto sucede con los subprocesos de trabajo, el subproceso principal está esperando (unir) hasta que todas las tareas en la cola se realicen, lo que ocurrirá cuando los subprocesos hayan enviado el marcador queue.task_done el mismo número de veces que los mensajes en la cola . En ese punto el hilo principal termina y sale. Ya que estos son hilos de deamon, cierran también.

Esto es genial, hilos y colas. Es una de las partes realmente buenas de Python. Escuchará todo tipo de cosas acerca de cómo se enreda la hebra en Python con la GIL y demás. Pero si sabe dónde usarlos (como en este caso con E / S de red), realmente acelerarán las cosas para usted. La regla general es que si está enlazado a E / S, pruebe y pruebe los subprocesos; Si está vinculado a la CPU, los subprocesos probablemente no sean una buena idea, tal vez intente procesos en su lugar.

buena suerte,

Micro

No creo que la Queue sea ​​necesaria en este caso. Usando solo Thread :

 import threading, urllib2, time hosts = ["http://yahoo.com", "http://google.com", "http://amazon.com", "http://ibm.com", "http://apple.com"] class ThreadUrl(threading.Thread): """Threaded Url Grab""" def __init__(self, host): threading.Thread.__init__(self) self.host = host def run(self): #grabs urls of hosts and prints first 1024 bytes of page url = urllib2.urlopen(self.host) print url.read(1024) start = time.time() def main(): #spawn a pool of threads for i in range(len(hosts)): t = ThreadUrl(hosts[i]) t.start() main() print "Elapsed Time: %s" % (time.time() - start)