2016-08-14 5 views
1

So habe ich viele Dateien von einem Server herunterladen. Über 1000 ... Also dachte ich, ich würde ein Skript schreiben, das das für mich tut, das Multithread ist, so dass ich nicht ewig warten muss, bis es fertig ist. Das Problem ist, dass es eine Reihe von Fehlern ausspuckt. Ich habe nach diesem gesucht, aber konnte wirklich nichts finden, das mit dem Fehler verbunden zu sein schien, den ich habe, da ich keine Ausgabe in meinen anderen threads drucke.Python und Multithreading sys.excepthook fehlt

mein Plan war es, die Threads-Kette sich gegenseitig zu starten, so dass sie nicht zufällig eine Datei zweimal nehmen und eine andere Datei überspringen.

danke für jede Hilfe!

mylist = [list of filenames in here] 

mycount = 0 

def download(): 
    global mycount 
    url = "http://myserver.com/content/files/" + mylist[mycount] 
    myfile = urllib2.urlopen(url) 
    with open(mylist[mycount],'wb') as output: 
     output.write(myfile.read()) 


def chain(): 
    global mycount 
    if mycount <= len(mylist) - 1: 
     thread.start_new_thread(download,()) 
     mycount = mycount + 1 
     chain() 

chain() 
+0

Können Sie einen Fehler posten? Die Python-Rekursionstiefe kann 1000 sein. Setzen Sie den Thread-Generator stattdessen in eine for-Schleife. – tdelaney

+0

BTW Ihr Code wird immer noch nicht funktionieren. Zu dem Zeitpunkt, an dem der Thread ausgeführt wird, hat der Master-Thread mycount viele Male inkrementiert. Sie sollten den zu verarbeitenden Dateinamen an den Thread übergeben. Erwägen Sie stattdessen, einen Threadpool zu verwenden. – tdelaney

+0

@tdelaney Danke, werde zu einer for-Schleife wechseln und versuchen, auch hier ist der Fehler: http://puu.sh/qB2IW/42b809c5de.png Sie meinen als Tupelvariable Argument für die Thread-Startfunktion? Auch ich habe noch nie zuvor mit Thread-Pools gearbeitet. – Thomja

Antwort

0

Also schaffte ich es tatsächlich nach etwas mehr googeln und lesen zu arbeiten.

aktuellen Code:

mycount = 0 
mylistLoc = [] 
for index in range(len(mylist)): 
    mylistLoc.append(index) 

def download(mycount): 
global mylistLoc 
url = "http://myserver.com/content/zips/" + mylist[mycount] 
try: 
    myfile = urllib2.urlopen(url) 
    with open(mylist[mycount],'wb') as output: 
     output.write(myfile.read()) 
except: 
    print "Could not open URL: " + url 
mycount = mycount + 1 
mylistLoc = [mycount] 

from multiprocessing.dummy import Pool as ThreadPool 
pool = ThreadPool(50) 
pool.map(download, mylistLoc) 

Zunächst einmal möchte ich erwähnen, dass der Versuch: Aussage hat nichts mit dem Multi-Threading für alle Neulinge zu tun, die diese Zeilen lesen kann.

Aber ich fand diese Methode auf einem anderen Stackoverflow-Thread, der das ein bisschen besser erklärt.

How to use threading in Python?

Aber im Grunde, wenn ich das richtig verstehe, importieren Sie zunächst alle notwendigen Funktionen mit dem

from multiprocessing.dummy import Pool as ThreadPool 

Und dann setzen Sie, wie viele Threads Sie aktiv werden soll. Für mich war 50 gut. Aber lesen Sie mehr darüber, da zu viele Probleme verursachen können.

dann der Saft

pool.map(download, mylistLoc) 

Grundsätzlich Anruf Pool Karte für jede Zahl in mylistLoc.

Ich denke, es ist ein komisches System, aber was weiß ich. Es klappt. Außerdem bin ich selbst ein Neuling.

+1

Ihr ursprünglicher Code verwendet 1000 Threads und wahrscheinlich ging über einige Ressourcen-Limit. Die optimale Anzahl von Threads für einen Pool hängt von vielen Faktoren ab - Sie können mit verschiedenen Zahlen experimentieren, um zu sehen, was am besten funktioniert. Erwägen Sie, die Chunk-Größe beim Kartenaufruf auf 1 zu setzen. Andernfalls erhalten die Arbeiter viele URLs, mit denen sie in einem Stück arbeiten können. Mit einer kleinen Brockengröße können Arbeiter, die schnellere URLs greifen, mehr von ihnen bearbeiten und Sie beenden schneller. – tdelaney