Gibt es eine Pool-Klasse für Worker- Threads , ähnlich der Pool-Klasse des Multiprocessing-Moduls ?
Ich mag zum Beispiel die einfache Möglichkeit, eine Kartenfunktion zu parallelisieren
def long_running_func(p):
c_func_no_gil(p)
p = multiprocessing.Pool(4)
xs = p.map(long_running_func, range(100))
Ich möchte dies jedoch ohne den Aufwand für die Erstellung neuer Prozesse tun.
Ich weiß von der GIL. In meinem Anwendungsfall ist die Funktion jedoch eine E / A-gebundene C-Funktion, für die der Python-Wrapper die GIL vor dem eigentlichen Funktionsaufruf freigibt.
Muss ich meinen eigenen Threading-Pool schreiben?
from multiprocessing.pool import ThreadPool
.I know about the GIL. However, in my usecase, the function will be an IO-bound C function for which the python wrapper will release the GIL before the actual function call.
?Antworten:
Ich habe gerade herausgefunden , dass es tatsächlich ist ein Thread-basierte Pool - Schnittstelle im
multiprocessing
Modul, aber es ist etwas versteckt und nicht richtig dokumentiert.Es kann über importiert werden
Es wird mithilfe einer Dummy-Prozessklasse implementiert, die einen Python-Thread umschließt. Diese threadbasierte Prozessklasse befindet sich
multiprocessing.dummy
in der Dokumentation, die in den Dokumenten kurz erwähnt wird . Dieses Dummy-Modul soll die gesamte Multiprozessor-Schnittstelle basierend auf Threads bereitstellen.quelle
multiprocessing.dummy.Pool
/multiprocessing.pool.ThreadPool
sind dasselbe und beide Thread-Pools. Sie ahmen die Schnittstelle eines Prozesspools nach, sind jedoch vollständig in Bezug auf das Threading implementiert. Lesen Sie die Dokumente erneut, Sie haben sie rückwärts erhalten.multiprocessing.dummy
Repliziert die API vonmultiprocessing
, ist aber nicht mehr als ein Wrapper um dasthreading
Modul."multiprocessing
Im Allgemeinen geht es um Prozesse, aber um das Wechseln zwischen Prozessen und Threads zu ermöglichen, haben sie (meistens) diemultiprocessing
API inmultiprocessing.dummy
Threads repliziert , jedoch nicht mit Prozessen. Ziel ist es, Ihnen zuimport multiprocessing.dummy as multiprocessing
ermöglichen, prozessbasierten Code in threadbasierten Code zu ändern.In Python 3 können Sie Folgendes verwenden
concurrent.futures.ThreadPoolExecutor
:Weitere Informationen und Beispiele finden Sie in den Dokumenten .
quelle
sudo pip install futures
ThreadPoolExecutor
undmultiprocessing.dummy.Pool
?Ja, und es scheint (mehr oder weniger) dieselbe API zu haben.
quelle
ThreadPool
unterscheidet sich vonPool
. Richtiger Import istfrom multiprocessing.pool import ThreadPool
.Für etwas sehr Einfaches und Leichtes (von hier leicht modifiziert ):
Um Rückrufe nach Abschluss der Aufgabe zu unterstützen, können Sie den Rückruf einfach zum Aufgabentupel hinzufügen.
quelle
Queue.get()
blockiert), bis das Programm endet. Danach werden sie automatisch beendet.Queue.join()
wird tatsächlich in die Task-Warteschlange aufgenommen, nicht in Worker-Threads. Wenn die Warteschlange leer ist, wirdwait_completion
zurückgegeben, das Programm wird beendet und Threads werden vom Betriebssystem geerntet.pool.wait_completion()
zurückkehrt. Das Ergebnis ist, dass Threads einfach weiter aufgebaut werden.Hallo, um den Thread-Pool in Python zu verwenden, können Sie diese Bibliothek verwenden:
und dann für die Verwendung, diese Bibliothek wie folgt:
Die Threads geben die Anzahl der gewünschten Threads an, und Aufgaben sind eine Liste der Aufgaben, die dem Dienst am häufigsten zugeordnet sind.
quelle
.close()
und.join()
-Aufrufe verpasst und das führt.map()
dazu , dass alle Threads beendet werden. Nur eine Warnung.Hier ist das Ergebnis, das ich schließlich verwendet habe. Es ist eine modifizierte Version der Klassen von dgorissen oben.
Datei:
threadpool.py
Den Pool benutzen
quelle
#!/usr/bin/python3
)for i, d in enumerate(delays):
deni
Wert und ignorieren ihn dann ?i
während eines Laufs drucken wollten .create_task
es? Wofür ist das?Der Aufwand für die Erstellung der neuen Prozesse ist minimal, insbesondere wenn es sich nur um vier handelt. Ich bezweifle, dass dies ein Leistungs-Hotspot Ihrer Anwendung ist. Halten Sie es einfach, optimieren Sie, wo Sie müssen und wohin die Profilerstellungsergebnisse zeigen.
quelle
Es ist kein Thread-basierter Pool integriert. Es kann jedoch sehr schnell sein, eine Produzenten- / Konsumentenwarteschlange mit der
Queue
Klasse zu implementieren .Von: https://docs.python.org/2/library/queue.html
quelle
concurrent.futures
Modul nicht mehr der Fall .from multiprocessing.pool import ThreadPool