concurrent.futures
http://docs.python.jp/3/library/concurrent.futures.html
Ein neues Standardpaket in Python 3.2, mit dem die parallele Taskverarbeitung mit mehreren Threads und Prozessen problemlos implementiert werden kann.
ThreadPoolExecutor und ProcessPoolExecutor werden durch Erben der Basisklasse Executor implementiert, und Sie können mit beinahe derselben Schnittstelle schreiben.
Da es sich um ein Standardpaket in Python 3.2 handelt, muss es nicht installiert werden. Backport ist für 2.6 und höher verfügbar.
python
pip install futures
import concurrent.futures
import hashlib
def digest(t): #Funktion zum angemessenen Verbrauch von CPU-Ressourcen
hash = hashlib.sha256()
for i in range(t*1000000):
hash.update('hogehoge')
return hash.hexdigest()
if __name__=='__main__':
task_list = [1,1,1,2,2,3]
#Erstellen Sie ein Executor-Objekt
executor = concurrent.futures.ProcessPoolExecutor(max_workers=4)
#Senden Sie die Aufgabe an das Executor-Objekt und erhalten Sie die gleiche Anzahl zukünftiger Objekte.
#Die Aufgabenausführung ist Senden()Es beginnt ab dem Moment, in dem Sie anrufen.
futures = [executor.submit(digest,t) for t in task_list]
#Warten Sie auf den Abschluss jeder Zukunft und erhalten Sie das Ergebnis.
# as_completed()Gibt einen Iterator zurück, der die Elemente der angegebenen Futures in der Reihenfolge ihrer Fertigstellung durchläuft.
#Wenn keine Aufgabe abgeschlossen ist, wird sie blockiert, bis eine abgeschlossen ist.
for future in concurrent.futures.as_completed(futures):
print(future.result()) # digest()Der Rückgabewert von wird angezeigt.
#Warten Sie, bis alle Aufgaben abgeschlossen und bereinigt sind.
#Nicht erledigte Aufgaben werden blockiert.
# (Einen Sohn_Da alles erledigt ist, sollte es keine Aufgaben geben, die zu diesem Zeitpunkt noch nicht erledigt wurden.)
executor.shutdown()
Wenn Sie "ProcessPoolExecutor" durch "ThreadPoolExecutor" ersetzen, funktioniert dies in mehreren Threads anstelle von mehreren Prozessen.
ProcessPoolExecutor wird durch prozessübergreifende Kommunikation realisiert, daher gibt es einige Einschränkungen.
Funktionsargumente und Rückgabewerte müssen Objekte sein, die mit pickle serialisiert werden können.
Die Funktion selbst muss auch zwischen Prozessen übergeben werden. Keine Instanzmethode. Lambda-Typ ist OK.
Auch wenn die globale Variable als Nebeneffekt in der Funktion neu geschrieben wird, wird sie im aufrufenden Prozess nicht berücksichtigt.
CPython implementiert Global Interpreter Lock, sodass nicht mehrere Threads gleichzeitig Python-Code in einem Prozess ausführen können. Bei einer Aufgabe, die Python-Code wie den obigen Beispielcode ausführt, erfolgt die Verarbeitung fast sequentiell, auch wenn sie mit ThreadPoolExecutor parallelisiert ist, sodass die Ausführungszeit keinen großen Nutzen bringt. (Es ist effektiv für die Verarbeitung mit viel Kommunikations- und E / A-Wartezeit.)
Recommended Posts