Frage

Ich schreibe eine GUI-Anwendung in Pyglet , die Dutzende bis Hunderte von Thumbnails aus dem Internet anzuzeigen hat . Gerade jetzt, ich bin mit urllib.urlretrieve sie zu packen, aber diese Blöcke jedes Mal, bis sie fertig sind, und greift nur einen nach dem anderen.

Ich würde es vorziehen, sie parallel zum Herunterladen und haben jeweils eine Anzeige, sobald es fertig ist, ohne dass die GUI an einer beliebigen Stelle zu blockieren. Was ist der beste Weg, dies zu tun?

Ich weiß nicht viel über Themen, aber es sieht aus wie das Threading Modul könnte helfen? Oder vielleicht gibt es einige einfache Weise, die ich übersehen habe.

War es hilfreich?

Lösung

Sie werden wahrscheinlich von threading profitieren oder multiprocessing Module. Sie eigentlich gar nicht selbst all jene Thread-basierten Klassen erstellen müssen, gibt es eine einfachere Methode Pool.map:

from multiprocessing import Pool

def fetch_url(url):
    # Fetch the URL contents and save it anywhere you need and
    # return something meaningful (like filename or error code),
    # if you wish.
    ...

pool = Pool(processes=4)
result = pool.map(f, image_url_list)

Andere Tipps

Wie Sie vermutet, ist dies eine perfekte Situation für Threading. Hier eine kurze Anleitung, die ich ungeheuer gefunden hilfreich, wenn meine erste Bit Einfädeln in python zu tun.

Wie Sie richtig angegeben ist, können Sie eine Anzahl von Threads erstellen, von denen jede für die Durchführung urlretrieve Operationen zuständig ist. Dies ermöglicht es der Hauptthread ohne Unterbrechung fortzusetzen.

Hier ist ein Tutorial in Python auf Threading: http://heather.cs.ucdavis.edu/~matloff/Python/ PyThreads.pdf

Hier ist ein Beispiel dafür, wie threading.Thread zu verwenden. Ersetzen Sie einfach den Klassennamen mit Ihrem eigenen und der Lauffunktion mit Ihrem eigenen. Beachten Sie, dass threading groß ist für IO-Anwendungen wie Ihre beschränkt und kann es wirklich beschleunigen. Mit pythong streng für die Berechnung in Standard-Python-Threading, da hilft nicht nur ein Thread zu einem Zeitpunkt berechnen kann.

import threading, time
class Ping(threading.Thread):
    def __init__(self, multiple):
        threading.Thread.__init__(self)
        self.multiple = multiple
    def run(self):
        #sleeps 3 seconds then prints 'pong' x times
        time.sleep(3)
        printString = 'pong' * self.multiple

pingInstance = Ping(3)
pingInstance.start() #your run function will be called with the start function
print "pingInstance is alive? : %d" % pingInstance.isAlive() #will return True, or 1
print "Number of threads alive: %d" % threading.activeCount()
#main thread + class instance
time.sleep(3.5)
print "Number of threads alive: %d" % threading.activeCount()
print "pingInstance is alive?: %d" % pingInstance.isAlive()
#isAlive returns false when your thread reaches the end of it's run function.
#only main thread now

Sie haben diese Möglichkeiten:

  • Themen: einfachste, aber nicht gut nicht maßstabs
  • Verdreht:. Mittelschwer, skaliert gut, aber Aktien CPU aufgrund GIL und sein Single-Threaded
  • Multi: am härtesten. Skaliert gut, wenn Sie wissen, wie Sie Ihre eigene Ereignisschleife schreiben.

Ich empfehle die Verwendung von Threads nur, wenn Sie einen industriellen Maßstab Abholer benötigen.

Sie müssen entweder Threads verwenden, oder eine asynchrone Netzwerkbibliothek wie Verdrehte . Ich vermute, dass Threads könnte in Ihrem speziellen Anwendungsfall einfacher sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top