2010-11-09 24 views
6
import threading 
import Queue 
import urllib2 
import time 

class ThreadURL(threading.Thread): 

    def __init__(self, queue): 
     threading.Thread.__init__(self) 

     self.queue = queue 

    def run(self): 
     while True: 
      host = self.queue.get() 
      sock = urllib2.urlopen(host) 
      data = sock.read() 

      self.queue.task_done() 

hosts = ['http://www.google.com', 'http://www.yahoo.com', 'http://www.facebook.com', 'http://stackoverflow.com'] 
start = time.time() 

def main(): 
    queue = Queue.Queue() 

    for i in range(len(hosts)): 
     t = ThreadURL(queue) 
     t.start() 

    for host in hosts: 
     queue.put(host) 

    queue.join() 

if __name__ == '__main__': 
    main() 
    print 'Elapsed time: {0}'.format(time.time() - start) 

He estado tratando de entender cómo realizar Threading y después de algunos tutoriales, he llegado a lo anterior.Necesito ayuda con el enhebrado/cola de Python

Lo que se supone que debe hacer es:

  1. Initialiase la cola
  2. crear mi conjunto de subprocesos y luego hacen cola en la lista de los ejércitos
  3. Mi clase ThreadURL debe entonces comenzar a trabajar una vez al host está en la cola y leer los datos del sitio web
  4. el programa debe terminar

lo que yo quiero saber antes que nada, es decir, una ¿Estoy haciendo esto correctamente? ¿Es esta la mejor manera de manejar los hilos?

segundo lugar, mi programa no puede salir. Imprime la línea Elapsed time y luego se cuelga allí. Tengo que matar mi terminal para que se vaya. Supongo que esto se debe a mi uso incorrecto de queue.join()?

Respuesta

6

Su código se ve bien y es bastante limpio.

La razón de su aplicación aún "cuelga" es que los subprocesos de trabajo están aún en marcha, en espera de la aplicación principal de poner algo en la cola, a pesar de que el hilo principal está terminado.

La forma más sencilla de solucionar este problema es marcar los hilos como demonios, haciendo t.daemon = True antes de su llamada para comenzar. De esta manera, los hilos no bloquearán la detención del programa.

2

se ve bien. yann tiene razón acerca de la sugerencia daemon. eso arreglará tu caída. mi única pregunta es por qué usar la cola en absoluto? no está haciendo ninguna comunicación cruzada, por lo que parece que podría enviar la información del host como un arg a ThreadURL init() y soltar la cola.

nada malo en ello, pregunto.

+0

Utilicé Cola porque eso es lo que la mayoría de los ejemplos/tutoriales que leí estaban usando. ¿Por qué una cola solo es útil cuando se envían datos entre hilos? La única información que pude encontrar sobre enhebrar/hacer cola fueron los tutoriales (que mostraban código y no mucha información) y los documentos oficiales que me resultaban demasiado complejos, un principiante de enhebrado, para comprender. – dave

+1

si solo está iniciando un hilo por host, está bien renunciar a las colas y pasar un solo host a __init __(). pero considere el caso donde tiene una gran lista de hosts que quiere alimentar a un número limitado de hilos. usarías una cola para distribuir el trabajo. –

1

Una cosa, en la función de ejecución hilo, el bucle Es cierto tiempo, si alguna excepción que ocurrió, la task_done() puede no ser llamado sin embargo, el get() ya ha sido llamado. Por lo tanto, la cola.join() nunca puede terminar.

Cuestiones relacionadas