2012-03-29 3 views
4

Ich habe ein Stück Code bekommt:Python 2.5 - Multi-Threaded-for-Schleife

for url in get_lines(file): 
    visit(url, timeout=timeout) 

Es wird URLs aus der Datei und besucht sie (von urllib2) in for-Schleife.

Ist es möglich, dies in wenigen Threads zu tun? Zum Beispiel 10 Besuche gleichzeitig.


Ich habe versucht:

for url in get_lines(file): 
    Thread(target=visit, args=(url,), kwargs={"timeout": timeout}).start() 

Aber es funktioniert nicht - keine Wirkung, werden URLs besucht normalerweise.


Die vereinfachte Version der Funktion Besuch:

def visit(url, proxy_addr=None, timeout=30): 
    (...) 
    request = urllib2.Request(url) 
    response = urllib2.urlopen(request) 
    return response.read() 
+1

'Thread (...). Start' sollte einen neuen Thread zur Ausführung von' visit' erzeugen. Woher wissen Sie, dass der Zugriff sequenziell ist? – ArjunShankar

Antwort

4

Um auf senderle Antwort zu erweitern, können Sie die Pool-Klasse verwenden, können in Multiprozessing dies leicht zu tun:

from multiprocessing import Pool 
pool = Pool(processes=5) 
pages = pool.map(visit, get_lines(file)) 

Wenn die Kartenfunktion gibt dann „Seiten“ wird eine Liste der Inhalte der URLs sein. Sie können die Anzahl der Prozesse auf das für Ihr System geeignete einstellen.

+0

Ich habe gerade festgestellt, dass Sie Python 2.5 in der Frage angegeben haben, und Multiprocessing war neu in 2.6. Wenn Sie nicht upgraden können, ist das möglicherweise nicht so nützlich für Sie. Entschuldigung. – JoeZuntz

1

Ich vermute, dass Sie in die Global Interpreter Lock ausgeführt haben. Grundsätzlich kann threading in Python keine Parallelität erreichen, was Ihr Ziel zu sein scheint. Sie müssen stattdessen multiprocessing verwenden.

multiprocessing ist entworfen, um eine ungefähr analoge Schnittstelle zu threading zu haben, aber es hat ein paar Macken. Ihre visit Funktion wie oben geschrieben sollte richtig funktionieren, glaube ich, weil es in einem funktionalen Stil geschrieben ist, ohne Nebenwirkungen.

In multiprocessing entspricht die Klasse Process der Klasse Thread in threading. Es hat alle die gleichen Methoden, so dass es in diesem Fall ein Drop-In-Ersatz ist. (Obwohl ich glaube, könnten Sie pool als JoeZuntz schlägt verwenden - aber ich würde testen mit dem Grunde Process Klasse zuerst, um zu sehen, ob es das Problem behebt.)

+0

Hmm, was ist mit der Tatsache, dass GIL während der I/O freigegeben wird ?: http://docs.python.org/glossary.html#term-global-interpreter-lock – ArjunShankar

+0

@ArjunShankar, dachte ich, aber ich ' Ich bin mir nicht sicher, ob das in diesem Fall zutrifft. Möglicherweise könnte es akzeptabel gemacht werden, wenn die Threads reine I/O-Threads wären, aber der Übergang zu Multiprocessing sollte auch funktionieren und erweiterbarer sein. – senderle

+0

Einverstanden. Ich war nur überrascht von dem Kommentar des OPs, dass Threading "keine Wirkung hat, URLs werden normal besucht". Also jetzt warten auf OP Follow-up. – ArjunShankar