Ich recherchierte zuerst und konnte keine Antwort auf meine Frage finden. Ich versuche, mehrere Funktionen in Python parallel auszuführen.
Ich habe so etwas:
files.py
import common #common is a util class that handles all the IO stuff
dir1 = 'C:\folder1'
dir2 = 'C:\folder2'
filename = 'test.txt'
addFiles = [25, 5, 15, 35, 45, 25, 5, 15, 35, 45]
def func1():
c = common.Common()
for i in range(len(addFiles)):
c.createFiles(addFiles[i], filename, dir1)
c.getFiles(dir1)
time.sleep(10)
c.removeFiles(addFiles[i], dir1)
c.getFiles(dir1)
def func2():
c = common.Common()
for i in range(len(addFiles)):
c.createFiles(addFiles[i], filename, dir2)
c.getFiles(dir2)
time.sleep(10)
c.removeFiles(addFiles[i], dir2)
c.getFiles(dir2)
Ich möchte func1 und func2 aufrufen und sie gleichzeitig ausführen lassen. Die Funktionen interagieren nicht miteinander oder mit demselben Objekt. Im Moment muss ich warten, bis func1 fertig ist, bevor func2 startet. Wie mache ich so etwas wie das Folgende:
process.py
from files import func1, func2
runBothFunc(func1(), func2())
Ich möchte in der Lage sein, beide Verzeichnisse nahezu zeitgleich zu erstellen, da ich jede Minute zähle, wie viele Dateien erstellt werden. Wenn das Verzeichnis nicht vorhanden ist, wird mein Timing beeinträchtigt.
Antworten:
Sie könnten
threading
oder verwendenmultiprocessing
.Aufgrund Besonderheiten der CPython ,
threading
ist unwahrscheinlich wahre Parallelität zu erreichen. Aus diesem Grundmultiprocessing
ist in der Regel eine bessere Wahl.Hier ist ein vollständiges Beispiel:
Die Mechanismen zum Starten / Verbinden von untergeordneten Prozessen können leicht in eine Funktion eingekapselt werden, die wie folgt aussieht
runBothFunc
:quelle
Dies kann elegant mit Ray erfolgen , einem System, mit dem Sie Ihren Python-Code einfach parallelisieren und verteilen können.
Um Ihr Beispiel zu parallelisieren, müssen Sie Ihre Funktionen mit dem
@ray.remote
Dekorator definieren und sie dann mit aufrufen.remote
.Wenn Sie dasselbe Argument an beide Funktionen übergeben und das Argument groß ist, können Sie dies effizienter verwenden
ray.put()
. Dadurch wird vermieden, dass das große Argument zweimal serialisiert und zwei Speicherkopien davon erstellt werden:Wenn
func1()
undfunc2()
Rückkehr Ergebnisse, müssen Sie den Code neu zu schreiben , wie folgt:Die Verwendung von Ray gegenüber dem Multiprocessing- Modul bietet eine Reihe von Vorteilen . Insbesondere wird derselbe Code sowohl auf einem einzelnen Computer als auch auf einem Cluster von Computern ausgeführt. Weitere Vorteile von Ray finden Sie in diesem verwandten Beitrag .
quelle
Wenn Ihre Funktionen hauptsächlich E / A-Arbeit (und weniger CPU-Arbeit) ausführen und Sie Python 3.2+ haben, können Sie einen ThreadPoolExecutor verwenden :
Wenn Ihre Funktionen hauptsächlich CPU-Arbeit (und weniger E / A-Arbeit) ausführen und Sie Python 2.6+ haben, können Sie das Multiprozessor- Modul verwenden:
quelle
Wenn Sie ein Windows-Benutzer sind und Python 3 verwenden, hilft Ihnen dieser Beitrag bei der parallelen Programmierung in Python. Wenn Sie die Poolprogrammierung einer normalen Multiprozessor-Bibliothek ausführen, wird eine Fehlermeldung bezüglich der Hauptfunktion in Ihrem Programm angezeigt. Dies liegt daran, dass Windows keine fork () -Funktionalität hat. Der folgende Beitrag gibt eine Lösung für das erwähnte Problem.
http://python.6.x6.nabble.com/Multiprocessing-Pool-woes-td5047050.html
Da ich Python 3 verwendet habe, habe ich das Programm ein wenig wie folgt geändert:
Nach dieser Funktion wird auch der obige Problemcode ein wenig wie folgt geändert:
Und ich bekam die Ausgabe als:
Ich denke, dass dieser Beitrag für einige der Windows-Benutzer nützlich sein kann.
quelle
Es gibt keine Möglichkeit zu garantieren, dass zwei Funktionen synchron miteinander ausgeführt werden. Dies scheint genau das zu sein, was Sie tun möchten.
Das Beste, was Sie tun können, ist, die Funktion in mehrere Schritte aufzuteilen und dann zu warten, bis beide an kritischen Synchronisationspunkten beendet sind, indem Sie
Process.join
die Antwort von like @ aix verwenden.Dies ist besser als
time.sleep(10)
weil Sie keine genauen Timings garantieren können. Wenn Sie explizit warten, sagen Sie, dass die Funktionen ausgeführt werden müssen, bevor Sie zum nächsten übergehen, anstatt davon auszugehen, dass sie innerhalb von 10 ms ausgeführt werden, was nicht garantiert ist, basierend auf dem, was sonst noch auf dem Computer vor sich geht.quelle
Scheint, als hätten Sie eine einzige Funktion, die Sie für zwei verschiedene Parameter aufrufen müssen. Dies kann elegant mit einer Kombination von
concurrent.futures
undmap
mit Python 3.2+ erfolgenWenn Ihre Operation an E / A gebunden ist, können Sie Folgendes verwenden
ThreadPoolExecutor
:Beachten Sie, wie
map
hiermap
Ihre Funktion zur Liste der Argumente verwendet wird.Wenn Ihre Funktion an die CPU gebunden ist, können Sie sie verwenden
ProcessPoolExecutor
Wenn Sie sich nicht sicher sind, können Sie einfach beide ausprobieren und sehen, welche Ihnen bessere Ergebnisse liefert.
Wenn Sie Ihre Ergebnisse ausdrucken möchten, können Sie dies einfach tun:
quelle