Python-Multiprocessing-Protokollierung
In diesem Artikel wird das Konzept der Mehrfachverarbeitung erläutert. Danach werden wir die Mehrfachverarbeitung in Python und die Protokollbehandlung für die Mehrfachverarbeitung mit Python-Code besprechen.
Multiprocessing
Multiprocessing ist ein Computerparadigma, bei dem mehr als ein Prozessor gleichzeitig verschiedene Teile desselben Programms verarbeitet.
Die in Multiprocessing-Betriebssystemen ausgeführten Anwendungen sind in kleinere Subroutinen unterteilt, die unabhängig voneinander ausgeführt werden, indem sie verschiedenen Prozessoren zugewiesen werden, um die Leistung zu verbessern.
Multiprocessing hat zwei verschiedene Arten:
- Symmetric Multiprocessing: Bei dieser Multiprocessing-Technik verwaltet ein einzelnes Betriebssystem mehr als einen Computerprozessor mit gemeinsam genutztem Hauptspeicher. Im Allgemeinen unterstützt ein Computersystem mit Multiprozessorleistung symmetrisches Multiprocessing.
- Asymmetrisches Multiprocessing: Bei diesem Multiprocessing wird einem Computerprozessor zugewiesen, betriebssystembezogene Aufgaben zu handhaben, und einem anderen Computerprozessor werden anwendungsbezogene Aufgaben zugewiesen. Es wird im Vergleich zu symmetrischer Mehrfachverarbeitung als ineffizient angesehen, da ein Prozessor im gleichen Zeitintervall bei asymmetrischer Mehrfachverarbeitung im Leerlauf sein kann und ein anderer vollständig beschäftigt sein kann.
Multiprocessing in Python
In Python wird die Bibliothek multiprocessing
für Multiprocessing-Aufgaben verwendet.
Betrachten Sie das folgende Beispiel:
import multiprocessing
def func1(arg):
print("func1: with parameter", arg)
def func2(arg):
print("func2: with parameter", arg)
if __name__ == "__main__":
process1 = multiprocessing.Process(target=func1, args=(1,))
process2 = multiprocessing.Process(target=func2, args=(2,))
process1.start()
process2.start()
process1.join()
process2.join()
print("Processes Ended")
Im obigen Code verwenden wir import multiprocessing
, um das Modul multiprocessing
einzubinden. Ein Objekt der Klasse Process
wird verwendet, um einen Prozess zu erstellen.
Das Klassenobjekt Process
erhält target
(eine im Prozess auszuführende Funktion) als Parameter und args
als Argument der target
-Funktion.
Zum Starten des Prozesses wird eine Methode start
der Klasse Process
verwendet. Im obigen Beispiel haben wir zwei Prozesse gestartet.
Wir verwenden die Methode join
, um das aktuelle Programm so lange auszuführen, bis process1
und process2
nicht beendet werden.
Sobald process1
und process2
ihre Aufgaben erledigt haben, führt das aktuelle Programm die print("Processes Ended")
-Anweisung aus.
Die Ausgabe des obigen Programms sieht wie folgt aus:
func1: with parameter 1
func2: with parameter 2
Processes Ended
Prozess-ID in Python während der Mehrfachverarbeitung
Wir können auch die Prozess-ID (PID
) mit zwei verschiedenen Methoden drucken.
os.getpid()
- Objektvariable
pid
der KlasseProcess
Betrachten Sie den folgenden Code:
import multiprocessing
import os
def func1(arg):
print("func1: with parameter ", arg)
print("ID of func1 process:", os.getpid())
def func2(arg):
print("func2: with parameter ", arg)
print("ID of func2 process:", os.getpid())
if __name__ == "__main__":
process1 = multiprocessing.Process(target=func1, args=(1,))
process2 = multiprocessing.Process(target=func2, args=(2,))
process1.start()
process2.start()
print("Process 1 / function 1 PID: ", process1.pid)
print("Process 2 / function 2 PID: ", process2.pid)
process1.join()
process2.join()
print("Processes Ended")
Im obigen Beispiel zeigen os.getpid()
und process1.pid
die Prozess-IDs. Die Ausgabe des folgenden Codes lautet wie folgt:
Process 1 / function 1 PID: 11368
Process 2 / function 2 PID: 14876
func1: with parameter 1
ID of func1 process: 11368
func2: with parameter 2
ID of func2 process: 14876
Processes Ended
os.getpid()
und process1.pid
zeigen dieselbe Prozess-ID.
Multiprocessing mit der Klasse Pool
Eine Pool
-Klasse des Python multiprocessing
-Moduls wird verwendet, um dieselbe Funktion mit unterschiedlichen Eingabewerten parallel auszuführen. Betrachten Sie beispielsweise den folgenden Code:
import multiprocessing
def func1(arg):
print("func1: with parameter ", arg)
if __name__ == "__main__":
process_pool = multiprocessing.Pool(3)
process_pool.map(func1, [1, 2, 3])
process_pool.close()
process_pool.join()
Im obigen Code erstellt multiprocessing.Pool
drei Prozesse zum Aufrufen von func1
mit unterschiedlichen Argumenten. Die Ausgabe des folgenden Codes lautet wie folgt:
func1: with parameter 1
func1: with parameter 2
func1: with parameter 3
Multiprocessing-Protokollierung in Python
Wir können Informationen aus mehreren Prozessen protokollieren, indem wir Pythons multiprocessing
-Bibliothek verwenden. Es gibt verschiedene Methoden zum Protokollieren von Multiprocessing.
Wir können die Klassen logging.handlers
, QueueHandler
und QueueListener
in Python für die Protokollierung verwenden.
Betrachten Sie den folgenden Code:
import multiprocessing
import logging
import os
from logging.handlers import QueueHandler, QueueListener
def func(arg):
logging.info(
"Process/function with argument {} and PID {}".format(arg, os.getpid())
)
def Process_init(q):
queue_handler = QueueHandler(q)
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(queue_handler)
if __name__ == "__main__":
print("Main Started")
mp_queue = multiprocessing.Queue()
lg_handler = logging.StreamHandler()
lg_handler.setFormatter(
logging.Formatter("%(levelname)s: %(asctime)s - %(process)s - %(message)s")
)
queue_listener = QueueListener(mp_queue, lg_handler)
queue_listener.start()
process_pool = multiprocessing.Pool(2, Process_init, [mp_queue])
process_pool.map(func, [1, 2])
process_pool.close()
process_pool.join()
queue_listener.stop()
print("Main Ended")
Der obige Code definiert eine Funktion func
, die ein Argument akzeptiert.
Die Methode func
protokolliert einen String mit dem Argumentwert und der Prozess-ID. Wir erhalten die Prozess-ID mit os.getpid()
.
In der Methode main
erstellen wir für QueueListener
die Objekte multiprocessing.Queue()
und logging.StreamHandler()
. Mit dem handler.setFormatter
wird das Protokollformat eingestellt.
Wir erstellen zwei Prozesse mit dem Objekt multiprocessing.Pool
und rufen in beiden Prozessen die Methode func
mit 1
und 2
als Argumentwert auf.
Die Methode Process_init
wird verwendet, um den queue_handler
zu initialisieren. Die Ausgabe des obigen Codes ist wie folgt:
Der obige Code zeigt die Protokollinformationen für zwei Prozesse mit der Prozess-ID 7024
und 15680
.
Wir können die Informationen auch in einer log
-Datei protokollieren, indem wir die lg_handler = logging.StreamHandler()
-Anweisung durch lg_handler = logging.FileHandler('info.log')
ersetzen.
Der logging.FileHandler
erstellt eine Datei info.log
und speichert die Protokolle in der Datei info.log
.