2010-11-09 13 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) 

Ho cercato di capire come eseguire il threading e dopo alcuni tutorial, ho scoperto quanto sopra.Ho bisogno di assistenza con il threading/coda Python

Che si suppone di fare è:

  1. Initialiase coda
  2. creare la mia piscina filo e poi in coda l'elenco di host
  3. La mia classe ThreadURL dovrebbe poi iniziare a lavorare una volta che un host è in la coda e leggere i dati del sito web
  4. il programma dovrebbe terminare

Quello che voglio sapere in primo luogo fuori, ovvero un m lo faccio correttamente? È questo il modo migliore per gestire i thread?

In secondo luogo, il mio programma non riesce ad uscire. Stampa la riga Elapsed time e quindi si blocca lì. Devo uccidere il mio terminale per farlo andare via. Suppongo che ciò sia dovuto al mio errato utilizzo di queue.join()?

risposta

6

Il tuo codice sembra buono ed è abbastanza pulito.

Il motivo per cui l'applicazione "si blocca" è che i thread di lavoro sono ancora in esecuzione, in attesa che l'applicazione principale inserisca qualcosa nella coda, anche se il thread principale è terminato.

Il modo più semplice per risolvere questo problema è contrassegnare i thread come demoni, eseguendo t.daemon = True prima di avviare la chiamata. In questo modo, i thread non bloccheranno l'arresto del programma.

2

sembra a posto. yann ha ragione riguardo al suggerimento demone. che risolverà il tuo blocco. la mia unica domanda è perché usare la coda? non stai facendo alcuna comunicazione cross-thread, quindi sembra che tu possa semplicemente inviare le informazioni dell'host come argomento a ThreadURL init() e rilasciare la coda.

niente di sbagliato, basta chiedersi.

+0

Ho usato la coda perché è quello che la maggior parte degli esempi/tutorial che ho letto stavano usando. Perché una coda è utile solo quando si inviano dati tra thread? L'unica informazione che ho trovato su threading/accodamento era tutorial (che mostravano codice e non molte informazioni) e documenti ufficiali che erano troppo complessi per me, un principiante di threading, per capire. – dave

+1

se si sta avviando un solo thread per host, va bene rinunciare alle code e passare un singolo host a __init __(). ma considera il caso in cui hai un ampio elenco di host che vuoi alimentare con un numero limitato di thread. useresti una coda per distribuire il lavoro. –

1

Una cosa, nella funzione di esecuzione del thread, mentre Ciclo vero, se si è verificata qualche eccezione, non è possibile chiamare task_done(), tuttavia è già stato chiamato get(). Quindi il queue.join() potrebbe non finire mai.

Problemi correlati