Multiprocessing in Python | Ein Anfängerleitfaden für Multiprocessing in Python

Inhalt

Im Zeitalter von Big Data, Python ist zur meistgesuchten Sprache geworden. In diesem Artikel, Konzentrieren wir uns auf einen bestimmten Aspekt von Python, der es zu einer der mächtigsten Programmiersprachen macht: Multiprocessing.

Jetzt, bevor wir in die Grundlagen des Multiprocessing eintauchen, Ich schlage vor, Sie lesen meinen vorherigen Artikel über Threading in Python, da es einen besseren Kontext für den aktuellen Artikel bieten kann.

Angenommen, Sie sind ein Grundschüler, dem die entmutigende Aufgabe des Multiplizierens übertragen wurde 1200 Zahlenpaare als Hausaufgabe. Angenommen, Sie können ein Zahlenpaar mit . multiplizieren 3 Sekunden. Später, gesamt, wird gebraucht 1200 * 3 = 3600 Sekunden, Was ist es 1 Zeit alle Hausaufgaben zu lösen. Aber du musst deine Lieblingsfernsehsendung nachholen 20 Protokoll.

Was würden Sie tun? Ein kluger Schüler, obwohl unehrlich, rufe drei weitere Freunde an, die eine ähnliche Fähigkeit haben und teile die Aufgabe auf. Dann hast du 250 Multiplikationsaufgaben auf deinem Teller, dass du in vervollständigst 250 * 3 = 750 Sekunden, nämlich, 15 Protokoll. Deswegen, Sie, zusammen mit seinen anderen 3 Freunde, wird die Aufgabe in beenden 15 Protokoll, geben 5 Minuten Zeit, um einen Snack zu sich zu nehmen und sich hinzusetzen, um Ihre Fernsehsendung zu sehen. Die Aufgabe dauerte nur 15 Minuten, wenn 4 von euch arbeiteten zusammen, was hätte ich sonst gebraucht 1 Zeit.

Dies ist die grundlegende Ideologie des Multiprocessing. Wenn Sie einen Algorithmus haben, der in verschiedene Worker unterteilt werden kann (Prozessoren), dann kannst du das Programm beschleunigen. Heute, die maschinen kommen mit 4,8 Ja 16 Kerne, die dann parallel implementiert werden können.

Mehrfachverarbeitung in der Datenwissenschaft

Multiprocessing hat zwei entscheidende Anwendungen in der Datenwissenschaft.

1. I/O-Prozesse

Jede datenintensive Pipeline hat Eingabe- und Ausgabeprozesse, bei denen Millionen von Datenbytes durch das System fließen. Wie gewöhnlich, der Lesevorgang (Eintrag) der Daten wird nicht lange dauern, aber das Schreiben von Daten in die Datenspeicher dauert lange. Der Schreibprozess kann parallel erfolgen, viel Zeit sparen.

53591Screenshot202021-04-2520at207-55-2420pm-2587887
44715Screenshot202021-04-2520at207-55-3520pm-8890286

2. Trainingsmodelle

Obwohl nicht alle Modelle parallel trainiert werden können, wenige Modelle haben inhärente Eigenschaften, die es ermöglichen, sie durch parallele Verarbeitung zu trainieren. Zum Beispiel, Der Random Forest-Algorithmus implementiert mehrere Entscheidungsbäume, um eine kumulative Entscheidung zu treffen. Diese Bäume können parallel gebaut werden. Eigentlich, die sklearn-API kommt mit einem Parameter namens n_jobs, die die Möglichkeit bietet, mehrere Arbeiter zu verwenden.

Mehrfachverarbeitung in Python mit Verfahren Klasse-

Jetzt packen wir es in die Finger multiprocesamiento Python-Bibliothek.

Schauen Sie sich den folgenden Code an

Importzeit

auf jeden Fall sleepy_man():
    drucken('Anfang zu schlafen')
    zeit.schlaf(1)
    drucken('Schlaf fertig')

tic = Zeit.Zeit()
schläfriger_mann()
schläfriger_mann()
toc = Zeit.Zeit()

drucken('Fertig in {:.4F} Sekunden'.format(klopf-tic))

Der obige Code ist einfach. Die Funktion schläfriger_mann Schlaf für eine Sekunde und wir rufen die Funktion zweimal auf. Wir erfassen die benötigte Zeit für die beiden Funktionsaufrufe und drucken die Ergebnisse. Die Ausgabe ist wie unten gezeigt.

Beginnen zu schlafen
Fertig geschlafen
Beginnen zu schlafen
Fertig geschlafen
Fertig in 2.0037 Sekunden

Dies wird erwartet, da wir die Funktion zweimal aufrufen und die Zeit aufzeichnen. Der Durchfluss ist im folgenden Diagramm dargestellt.

27376Screenshot202021-04-2420at209-31-2020pm-4414793

Lassen Sie uns nun Multiprocessing in den Code integrieren.

Multiprocessing importieren
Importzeit
auf jeden Fall sleepy_man():
    drucken('Anfang zu schlafen')
    zeit.schlaf(1)
    drucken('Schlaf fertig')

tic = Zeit.Zeit()
p1 = Multiprocessing.Prozess(target= sleepy_man)
p2 = Multiprocessing.Prozess(target= sleepy_man)
p1.start()
p2.start()
toc = Zeit.Zeit()

drucken('Fertig in {:.4F} Sekunden'.format(klopf-tic))

Hier Multiprocessing.Prozess (Ziel = sleepy_man) definiert eine Multithread-Instanz. Wir übergeben die erforderliche auszuführende Funktion, schläfriger_mann, als Argument. Wir aktivieren die beiden Instanzen durch p1.start ().

Die Ausgabe ist wie folgt:

Fertig in 0.0023 Sekunden
Beginnen zu schlafen
Beginnen zu schlafen
Fertig geschlafen
Fertig geschlafen

Beachte jetzt eines. Die Zeitstempel-Druckanweisung wurde zuerst ausgeführt. Das ist weil, zusammen mit den Multithread-Instanzen, die für die aktiviert sind schläfriger_mann Funktion, der Hauptcode der Funktion wurde separat parallel ausgeführt. Das folgende Flussdiagramm wird die Dinge klar machen.

97577Screenshot202021-04-2420at209-50-0420pm-6090268

Um den Rest des Programms auszuführen, nachdem die Multithread-Funktionen ausgeführt wurden, wir müssen die Funktion ausführen betreten().

Multiprocessing importieren
Importzeit

auf jeden Fall sleepy_man():
    drucken('Anfang zu schlafen')
    zeit.schlaf(1)
    drucken('Schlaf fertig')

tic = Zeit.Zeit()
p1 = Multiprocessing.Prozess(target= sleepy_man)
p2 = Multiprocessing.Prozess(target= sleepy_man)
p1.start()
p2.start()
p1.beitreten()
p2.beitreten()
toc = Zeit.Zeit()

drucken('Fertig in {:.4F} Sekunden'.format(klopf-tic))

Jetzt, der Rest des Codeblocks wird erst ausgeführt, nachdem die Multiprocessing-Aufgaben erledigt sind. Die Ausgabe ist unten gezeigt.

Beginnen zu schlafen
Beginnen zu schlafen
Fertig geschlafen
Fertig geschlafen
Fertig in 1.0090 Sekunden

Das Flussdiagramm ist unten gezeigt.

47314Screenshot202021-04-2420at2010-02-5520pm-3764739

Da die beiden Federungsfunktionen parallel laufen, die Funktion als Ganzes dauert ca. 1 Sekunde.

Wir können eine beliebige Anzahl von Multiprocessing-Instanzen definieren. Schau dir den Code unten an. Definieren 10 verschiedene Multiprocessing-Instanzen mit einer for-Schleife.

Multiprocessing importieren
Importzeit

auf jeden Fall sleepy_man():
    drucken('Anfang zu schlafen')
    zeit.schlaf(1)
    drucken('Schlaf fertig')

tic = Zeit.Zeit()

process_list = []
für mich in Reichweite(10):
    p = Multiprocessing.Prozess(target= sleepy_man)
    p.start()
    process_list.append(P)

für Prozess in Prozessliste:
    process.join()

toc = Zeit.Zeit()

drucken('Fertig in {:.4F} Sekunden'.format(klopf-tic))

Die Ausgabe des obigen Codes ist unten gezeigt.

Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig in 1.0117 Sekunden

Hier, die zehn Funktionsausführungen werden parallel abgearbeitet und, Daher, das ganze programm dauert nur eine sekunde. Jetzt hat meine Maschine keine 10 Prozessoren. Wenn wir mehr Prozesse definieren als unsere Maschine, Multiprocessing-Bibliothek verfügt über Logik zum Planen von Jobs. Du musst dir also keine Sorgen machen.

Wir können auch Argumente an die übergeben Verfahren Funktion mit Argumente.

Multiprocessing importieren
Importzeit

auf jeden Fall sleepy_man(Sek):
    drucken('Anfang zu schlafen')
    zeit.schlaf(Sek)
    drucken('Schlaf fertig')

tic = Zeit.Zeit()

process_list = []
für mich in Reichweite(10):
    p = Multiprocessing.Prozess(target= sleepy_man, Argumente = [2])
    p.start()
    process_list.append(P)

für Prozess in Prozessliste:
    process.join()

toc = Zeit.Zeit()

drucken('Fertig in {:.4F} Sekunden'.format(klopf-tic))

Die Ausgabe des obigen Codes ist unten gezeigt.

Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Beginnen zu schlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig geschlafen
Fertig in 2.0161 Sekunden

Da wir ein Argument übergeben, das schläfriger_mann Funktion geschlafen während 2 Sekunden statt 1 Sekunde.

Mehrfachverarbeitung in Python mit Schwimmbad Klasse-

Im letzten Codeschnipsel, wir führen aus 10 verschiedene Prozesse mit einer for-Schleife. Stattdessen, wir können das gebrauchen Schwimmbad Methode, dasselbe zu tun.

Multiprocessing importieren
Importzeit

auf jeden Fall sleepy_man(Sek):
    drucken('Beginne zu schlafen für {} Sekunden'.format(Sek))
    zeit.schlaf(Sek)
    drucken('Schlaf fertig für {} Sekunden'.format(Sek))

tic = Zeit.Zeit()

pool = multiprocessing.Pool(5)
pool.karte(schläfriger_mann, Bereich(1,11))
pool.schließen()

toc = Zeit.Zeit()

drucken('Fertig in {:.4F} Sekunden'.format(klopf-tic))

Pool-Multiprocessing (5) definiert die Anzahl der Arbeiter. Hier definieren wir die Zahl als 5. pool.karte () ist die Methode, die die Ausführung der Funktion auslöst. Wir nennen pool.karte (schläfriger_mann, Rang (1,11)). Hier, schläfriger_mann ist die aufzurufende Funktion mit den Parametern für die Ausführung von Funktionen definiert durch Rang (1,11) (normalerweise wird eine Liste übergeben). Die Ausgabe ist wie folgt:

Beginne zu schlafen für 1 Sekunden
Beginne zu schlafen für 2 Sekunden
Beginne zu schlafen für 3 Sekunden
Beginne zu schlafen für 4 Sekunden
Beginne zu schlafen für 5 Sekunden
Fertig geschlafen für 1 Sekunden
Beginne zu schlafen für 6 Sekunden
Fertig geschlafen für 2 Sekunden
Beginne zu schlafen für 7 Sekunden
Fertig geschlafen für 3 Sekunden
Beginne zu schlafen für 8 Sekunden
Fertig geschlafen für 4 Sekunden
Beginne zu schlafen für 9 Sekunden
Fertig geschlafen für 5 Sekunden
Beginne zu schlafen für 10 Sekunden
Fertig geschlafen für 6 Sekunden
Fertig geschlafen für 7 Sekunden
Fertig geschlafen für 8 Sekunden
Fertig geschlafen für 9 Sekunden
Fertig geschlafen für 10 Sekunden
Fertig in 15.0210 Sekunden

Schwimmbad -Klasse ist eine bessere Möglichkeit, Multiprocessing zu implementieren, da sie mithilfe des First-In-Programms Aufgaben auf verfügbare Prozessoren verteilt, zuerst raus. Es ist fast ähnlich wie die Map-Reduce-Architektur, im Wesentlichen, ordnet den Input verschiedenen Prozessoren zu und sammelt den Output aller Prozessoren als Liste. Laufende Prozesse werden im Speicher abgelegt und andere nicht laufende Prozesse werden außerhalb des Speichers abgelegt.

82629Screenshot202021-04-2520at2011-12-5020am-3213320

Während in Verfahren Klasse, alle Prozesse werden im Speicher ausgeführt und die Ausführung wird mit Hilfe der FIFO-Richtlinie geplant.

Vergleich der Zeitleistung, um perfekte Zahlen zu berechnen-

Bis jetzt, wir spielen mit multiprocesamiento Funktionen in schlafen Funktionen. Nehmen wir nun eine Funktion, die prüft, ob eine Zahl eine perfekte Zahl ist oder nicht. Für alle die es nicht wissen, eine Zahl ist eine perfekte Zahl, wenn die Summe ihrer positiven Teiler gleich der Zahl selbst ist. Wir listen die perfekten Zahlen kleiner oder gleich auf 100000. Wir implementieren es ab 3 Formen: Verwenden einer for regulären Schleife, mit multiprocess.Process () y Multiprozess.Pool ().

Verwenden eines Regulars für eine Schleife

Importzeit

auf jeden Fall ist_perfekt(n):
    sum_factors = 0
    für mich in Reichweite(1, n):
        Wenn (n % ich == 0):
            sum_factors = sum_factors + ich
    wenn (sum_factors == n):
        drucken('{} ist eine perfekte Zahl'.format(n))

tic = Zeit.Zeit()
für n im Bereich(1,100000):
    ist perfekt(n)
toc = Zeit.Zeit()

drucken('Fertig in {:.4F} Sekunden'.format(klopf-tic))

Das Ergebnis des obigen Programms ist unten gezeigt.

6 ist eine perfekte Zahl
28 ist eine perfekte Zahl
496 ist eine perfekte Zahl
8128 ist eine perfekte Zahl
Fertig in 258.8744 Sekunden

Verwenden einer Prozessklasse

Importzeit
Multiprocessing importieren

auf jeden Fall ist_perfekt(n):
    sum_factors = 0
    für mich in Reichweite(1, n):
        Wenn(n % ich == 0):
            sum_factors = sum_factors + ich
    wenn (sum_factors == n):
        drucken('{} ist eine perfekte Zahl'.format(n))

tic = Zeit.Zeit()

Prozesse = []
für mich in Reichweite(1,100000):
    p = Multiprocessing.Prozess(target=ist_perfekt, args=(ich,))
    Prozesse.anhängen(P)
    p.start()

für Prozess in Prozessen:
    process.join()

toc = Zeit.Zeit()
drucken('Fertig in {:.4F} Sekunden'.format(klopf-tic))

Das Ergebnis des obigen Programms ist unten gezeigt.

6 ist eine perfekte Zahl
28 ist eine perfekte Zahl
496 ist eine perfekte Zahl
8128 ist eine perfekte Zahl
Fertig in 143.5928 Sekunden

Wie konntest du sehen?, wir haben eine reduzierung von . erreicht 44,4% rechtzeitig, wenn wir Multiprocessing mit implementieren Verfahren Klasse, statt einer regulären for-Schleife.

Verwenden einer Pool-Klasse

Importzeit
Multiprocessing importieren

auf jeden Fall ist_perfekt(n):
    sum_factors = 0
    für mich in Reichweite(1, n):
        Wenn(n % ich == 0):
            sum_factors = sum_factors + ich
    wenn (sum_factors == n):
        drucken('{} ist eine perfekte Zahl'.format(n))

tic = Zeit.Zeit()
pool = multiprocessing.Pool()
pool.karte(ist perfekt, Bereich(1,100000))
pool.schließen()
toc = Zeit.Zeit()

drucken('Fertig in {:.4F} Sekunden'.format(klopf-tic))

Das Ergebnis des obigen Programms ist unten gezeigt.

6 ist eine perfekte Zahl
28 ist eine perfekte Zahl
496 ist eine perfekte Zahl
8128 ist eine perfekte Zahl
Fertig in 74.2217 Sekunden

Wie du siehst, im Vergleich zu einer regulären for-Schleife, wir haben eine reduzierung von . erreicht 71,3% in Rechenzeit, und im Vergleich zu den Verfahren Klasse, wir haben eine reduzierung von . erreicht 48,4% in Rechenzeit.

Deswegen, Es ist sehr offensichtlich, dass durch die Implementierung einer geeigneten Methode aus der multiprocesamiento Bücherei, können wir eine deutliche Reduzierung der Rechenzeit erreichen.

Die in diesem Artikel gezeigten Medien sind nicht Eigentum von DataPeaker und werden nach Ermessen des Autors verwendet.

Abonniere unseren Newsletter

Wir senden Ihnen keine SPAM-Mail. Wir hassen es genauso wie du.