[Python] Über Multi-Prozess

Über diesen Artikel

In diesem Artikel wird zusammengefasst, was Sie über Python Multi-Process gelernt haben.

Informationen zu Multiprozessen in Python

Wann wird Multi-Prozess verwendet? ⇒ Bei der Realisierung der Parallelverarbeitung ist es möglich, den Prozess als Mittel zur Realisierung aufzuteilen.

Anwendungen, die CPU-intensive Aufgaben auf einer Multi-Core-CPU ausführen, erfordern derzeit die Verwendung von Multi-Prozessen, um die Multi-Core-CPU nutzen zu können.

https://docs.python.org/ja/3/faq/library.html#can-t-we-get-rid-of-the-global-interpreter-lock

Vorteile von Multiprozessen in Python

Um den Prozess zu starten

Bevor ich den Quellcode mit mehreren Prozessen erwähne, werde ich erwähnen, wie ein neuer Prozess gestartet wird. In jeder Programmiersprache können Sie einen neuen Prozess starten, indem Sie ein Programm abspalten. In Python wird durch Ausführen von "os.fork ()" jeder Prozess in einem anderen Adressraum ausgeführt, nachdem der Speicherkontext die untergeordneten Prozesse kopiert hat. Unten die Quelle.

fork.py


import os

pid_list = []

def main():
    pid_list.append(os.getpid())
    child_pid = os.fork()

    if child_pid == 0:
        pid_list.append(os.getpid())
        print()
        print("Kind: こんにちは,私はKindプロセスです")
        print("Kind:Die PID-Nummer, die ich kenne, ist%s" % pid_list)
    
    else:
        pid_list.append(os.getpid())
        print()
        print("Elternteil:こんにちは,私はElternteilプロセスです")
        print("Elternteil:Die PID-Nummer des untergeordneten Prozesses lautet%d"%child_pid)
        print("Elternteil:Die PID-Nummer, die ich kenne, ist%s"%pid_list)

if __name__ == "__main__":
    main()

$python fork.py

Elternteil:こんにちは,私はElternteilプロセスです
Elternteil:Die PID-Nummer des untergeordneten Prozesses lautet 321
Elternteil:Die PID-Nummer, die ich kenne, ist[320, 320]ist

Kind: こんにちは,私はKindプロセスです
Kind:Die PID-Nummer, die ich kenne, ist[320, 321]ist

Der anfängliche Prozess hat dieselbe PID von 320, aber Sie können sehen, dass der untergeordnete Prozess 321 hinzugefügt hat und dass die beiden Prozesse keinen Speicherkontext gemeinsam nutzen.

Implementierung der prozessübergreifenden Kommunikation

Der Prozessspeicher wird standardmäßig nicht gemeinsam genutzt. Wenn Sie zwischen Prozessen kommunizieren möchten, müssen Sie einige Arbeiten ausführen. Um dies zu vereinfachen, bietet das Multiprozessor-Modul verschiedene Möglichkeiten zur Kommunikation zwischen Prozessen. Die folgenden zwei Methoden werden hier vorgestellt.

Über multiprocessing.Pipe

Die Pipe-Klasse hat ein ähnliches Konzept wie Unix- und Linux-Pipes. multiprocessing.Pipe () gibt ein Paar Connection-Objekte zurück, die beide Enden der Pipe darstellen. Im folgenden Beispiel (pipesample.py) gilt "parent_conn, child_conn = Pipe ()". Die Standardeinstellung "Pipe (True)" macht es bidirektional. Mit "Pipe (False)" ist die Pipe unidirektional, und mit "conn1", "conn2 = Pipe ()" ist "conn1" dem Empfangen von Nachrichten und "conn2" dem Senden gewidmet. Die Pipe-Klasse sendet und empfängt auch auswählbare Objekte.

Referenz-URL: https://docs.python.org/ja/2.7/library/multiprocessing.html#pipes-and-queues

pipesample.py


from multiprocessing import Process, Pipe

class CustomClass:
    pass

def work(connection):
    while True:
        instance = connection.recv()

        if instance:
            print("Kind:Erhalten:{}".format(instance))

        else:
            return

def main():
    parent_conn, child_conn = Pipe()

    child = Process(target=work, args=(child_conn,))

    for item in (
        42,
        'some string',
        {'one':1},
        CustomClass(),
        None,
    ):
        print("Elternteil:Senden:{}".format(item))
        parent_conn.send(item)
    
    child.start()
    child.join()

if __name__ == "__main__":
    main()
$python pipesample.py
Elternteil:Senden:42
Elternteil:Senden:some string
Elternteil:Senden:{'one': 1}
Elternteil:Senden:<__main__.CustomClass object at 0x7fc785a34ac8>
Elternteil:Senden:None
Kind:Erhalten:42
Kind:Erhalten:some string
Kind:Erhalten:{'one': 1}
Kind:Erhalten:<__main__.CustomClass object at 0x7fc785268978>

Wenn Sie die von "for item in (42, ..., None,):" erstellte Instanz an das Argument "parent.send ()" übergeben, wird der Prozess durch den Empfang von "child .recv ()" gepaart Der Status der Daten wird an übergeben. Sie können auch sehen, dass die Prozessadressen unterschiedlich sind.

Implementierung mit multiprocessing.sharedctypes

In der Klasse "multiprocessing.sharedctypes" wird ein gemeinsam genutzter Speicher erstellt und dort werden Datentypen (int type, double type usw.) erstellt. Bietet eine Möglichkeit zum Einfügen. Der Datentyp folgt C-Typ. Die grundlegendsten sind "Wert (typecode_or_type, * arg, lock = True)" und "Array (typecode_or_type, size_or_initializer, *, lock = True)". typecode_or_type bestimmt den Typ des zurückgegebenen Objekts. Es handelt sich entweder um einen ctypes-Typ oder einen Ein-Buchstaben-Typcode, wie er im Array-Modul verwendet wird. Da es schwierig ist, Liste, Wörterbuch, Namespace, Sperre usw. zu beschreiben, verwenden Sie in diesem Fall "multiprocessing.Manager". Referenz: https://docs.python.org/ja/3/library/multiprocessing.html#sharing-state-between-processes

valuearray.py


from multiprocessing import Process, Value, Array

def f(n,a):
    n.value = 3.141592
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == "__main__":
    num = Value('d', 0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print(num.value)
    print(arr[:])
$python valuearray.py
3.141592
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

Prozesspool verwenden

Die Verwendung von Multi-Prozessen anstelle von Threads erhöht den Overhead erheblich. Die Speichernutzung nimmt zu, insbesondere wenn jeder Prozess einen unabhängigen Speicherkontext hat. Wenn eine große Anzahl von untergeordneten Prozessen generiert wird, ist der schädliche Effekt daher größer als bei der Verarbeitung mit Threads. Für Anwendungen mit mehreren Prozessen ist das Erstellen eines Prozesspools eine gute Möglichkeit, die Ressourcennutzung zu steuern. Die Grundidee eines Prozesspools besteht darin, einen im Voraus festgelegten Prozess vorzubereiten und dann Elemente aus der Warteschlange zu entnehmen und zu verarbeiten. Anstatt den Prozess nach dem Eintreffen der zu verarbeitenden Aufgabe zu starten, starten Sie den Prozess im Voraus, sodass der Prozess unmittelbar nach der Zuweisung der Aufgabe startet.

Über die Pool Klasse

Diese Klasse kümmert sich um die komplizierte Verarbeitung, die mehrere Prozesse verwaltet.

Der folgende Quellcode verwendet die Google Map-API von GCP (Google Cloud Platform), um den Breiten- und Längengrad zu ermitteln, der den Namen der Stadt trifft. Durch Setzen von "POOL_SIZE = 4" werden vier parallel arbeitende Prozesse angegeben. Die Klasse "Pool" kann auch den Kontextmanager verwenden.

geocoding_by_multiprocessing.py



from multiprocessing import Pool

from gmaps import Geocoding

api = Geocoding(api_key='Geheimnis')

PLACES = (
    'Reykjavik','Vien','Zadar',
    'Venice','Wrocow','Bolognia',
    'Berlin','Dehil','New York',
    'Osaka'
)

POOL_SIZE = 4

def fetch_place(place):
    return api.geocode(place)[0]

def present_result(geocoded):
    print("{:s}, {:6.2f}, {:6.2f}".format(
        geocoded['formatted_address'],
        geocoded['geometry']['location']['lat'],
        geocoded['geometry']['location']['lng'],
    ).encode('utf-8'))

def main():
    with Pool(POOL_SIZE) as pool:
        results = pool.map(fetch_place, PLACES)
    
    for result in results:
        present_result(result)

if __name__ == "__main__":
    main()
    
$ python geocoding_by_multiprocessing.py
b'Reykjav\xc3\xadk, Iceland,  64.15, -21.94'
b'3110 Glendale Blvd, Los Angeles, CA 90039, USA,  34.12, -118.26'
b'Zadar, Croatia,  44.12,  15.23'
b'Venice, Metropolitan City of Venice, Italy,  45.44,  12.32'
b'Wroc\xc5\x82aw, Poland,  51.11,  17.04'
b'Bologna, Metropolitan City of Bologna, Italy,  44.49,  11.34'
b'Berlin, Germany,  52.52,  13.40'
b'Delhi, India,  28.70,  77.10'
b'New York, NY, USA,  40.71, -74.01'
b'Osaka, Japan,  34.69, 135.50'

Impressionen

Das Studium der Parallelverarbeitung ist schwierig. (Lol)

Verweise

Recommended Posts

[Python] Über Multi-Prozess
Über Python-Slices
Über die Python-Ausbeute
Über Python, Klasse
Über Python Decorator
Informationen zur Python-Referenz
Über Python-Dekorateure
Über Python für Schleife
Über Funktionsargumente (Python)
[Python] Memo über Funktionen
Zusammenfassung über Python3 + OpenCV3
Über Python für ~ (Bereich)
Asynchron mit Python verarbeiten
[Python] Memo Über Fehler
Informationen zur Python-Entwicklungsumgebung
Python: Über Funktionsargumente
Über Python Pyramid Traversal
Über Python3 ... (Ellipsenobjekt)
[Python] Kapitel 01-01 Über Python (Erster Python)
[Python] Informationen zur Standardeingabe
Über __all__ in Python
[Python] Informieren Sie sich über pip
Fabric unterstützt Python 3
Python
Informationen zu Python-Objekten und -Klassen
Informationen zu Python-Variablen und -Objekten
Über das Python-Modul venv
Multi-Prozess
Python-Anfänger-Memorandum-Funktion
Über die Aufzählungsfunktion (Python)
Über verschiedene Codierungen von Python 3
Über Perl, Python, PHP, Ruby
Informationen zu Python-Datums- und Zeitzone
Memorandum über Korrelation [Python]
Informationen zu Python-Zeichenfolgenvergleichsoperatoren
Über Python und reguläre Ausdrücke
Über die Funktionen von Python
Über "für _ in range ():" von Python
Informationen zu Python- und Betriebssystemoperationen
Python # Über Referenz und Kopie
Über Python sort () und reverse ()
Ein Hinweis zu [Python] __debug__
Python Hinweis: Über den Vergleich mit is
Informationen zur Installation der Serien Pwntools und Python2
Python: Ein Hinweis zu Klasse 1 "Abstract"
[Python] Lassen Sie uns kurz über die Einschlussnotation schreiben
Debuggen Sie das Python-Multiprozessprogramm mit VSCode
Über Python-Diktat und sortierte Funktionen
Über Python und Cython dtype
[Python] Was ist @? (Über Dekorateure)
Was war überraschend an Python-Klassen?
Über Python Pickle (cPickle) und Marschall
[Python] Über Executor und zukünftige Klassen
Informationen zur Grundlagenliste der Python-Grundlagen
Ein Hinweis zu Mock (Python-Mock-Bibliothek)
Kafka Python
Über LangID
Über CAGR