Python-Multiprocessing-Protokollierung

Dr. Muhammad Abdullah 15 Februar 2024
  1. Multiprocessing
  2. Multiprocessing in Python
  3. Multiprocessing-Protokollierung in Python
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:

  1. 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.
  2. 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.

  1. os.getpid()
  2. Objektvariable pid der Klasse Process

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:

Ausgabe für Multiprocessing-Protokollierung

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.

Verwandter Artikel - Python Multiprocessing