Registro de multiprocesamiento de Python

Dr. Muhammad Abdullah 15 febrero 2024
  1. multiprocesamiento
  2. Multiprocesamiento en Python
  3. Registro de multiprocesamiento en Python
Registro de multiprocesamiento de Python

Este artículo discutirá el concepto de multiprocesamiento. Después de esto, analizaremos el multiprocesamiento en Python y el manejo de registros para el multiprocesamiento mediante el código de Python.

multiprocesamiento

El multiprocesamiento es un paradigma informático en el que más de un procesador procesa simultáneamente diferentes partes del mismo programa.

La aplicación que se ejecuta en sistemas operativos de multiprocesamiento se divide en subrutinas más pequeñas que se ejecutan de forma independiente al asignarse a diferentes procesadores para mejorar el rendimiento.

El multiprocesamiento tiene dos tipos diferentes:

  1. Multiprocesamiento simétrico: en esta técnica de multiprocesamiento, un solo sistema operativo administra más de un procesador de computadora con memoria principal compartida. Generalmente, un sistema informático que tiene potencia de multiprocesamiento admite multiprocesamiento simétrico.
  2. Multiprocesamiento asimétrico: en este multiprocesamiento, se asigna un procesador de computadora para manejar tareas relacionadas con el sistema operativo, y otro procesador de computadora se asigna tareas relacionadas con la aplicación. Se considera ineficiente en comparación con el multiprocesamiento simétrico porque un procesador puede estar inactivo y otro puede estar completamente ocupado en el mismo intervalo de tiempo en el multiprocesamiento asimétrico.

Multiprocesamiento en Python

En Python, la biblioteca de multiprocesamiento se utiliza para tareas de multiprocesamiento.

Considere el siguiente ejemplo:

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")

En el código anterior, usamos importar multiprocesamiento para incluir el módulo multiprocesamiento. Un objeto de clase Proceso se utiliza para crear un proceso.

El objeto de clase Process recibe target (una función para ejecutar en el proceso) como parámetro y args como argumento de la función target.

Se utiliza un método start de la clase Process para iniciar el proceso. En el ejemplo anterior, iniciamos dos procesos.

Usamos el método join para seguir ejecutando el programa actual hasta que process1 y process2 no finalicen.

Una vez que process1 y process2 completan sus tareas, el programa actual ejecuta la sentencia print("Processes Ended").

La salida del programa anterior es la siguiente:

func1: with parameter 1
func2: with parameter 2
Processes Ended

ID de proceso en Python durante el multiprocesamiento

También podemos imprimir el ID del proceso (PID) mediante dos métodos diferentes.

  1. os.getpid()
  2. Variable miembro del objeto de la clase Process pid

Considere el siguiente código:

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")

En el ejemplo anterior, os.getpid() y process1.pid muestran los ID de proceso. La salida del siguiente código es la siguiente:

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

El os.getpid() y process1.pid muestran el mismo ID de proceso.

Multiprocesamiento con clase Pool

Se utiliza una clase Pool del módulo de multiprocesamiento de Python para ejecutar en paralelo la misma función con diferentes valores de entrada. Por ejemplo, considere el siguiente código:

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()

En el código anterior, multiprocessing.Pool crea tres procesos para llamar a func1 con diferentes argumentos. La salida del siguiente código es la siguiente:

func1: with parameter  1
func1: with parameter  2
func1: with parameter  3

Registro de multiprocesamiento en Python

Podemos registrar información de múltiples procesos utilizando la biblioteca de multiprocesamiento de Python. Existen diferentes métodos para registrar el multiprocesamiento.

Podemos usar las clases logging.handlers, QueueHandler y QueueListener en Python para el registro.

Considere el siguiente código:

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")

El código anterior define una función func que acepta un argumento.

El método func registra una cadena que tiene el valor del argumento y el ID del proceso. Obtenemos el ID del proceso usando os.getpid().

En el método main, creamos los objetos multiprocessing.Queue() y logging.StreamHandler() para QueueListener. El handler.setFormatter se utiliza para establecer el formato de registro.

Creamos dos procesos usando el objeto multiprocessing.Pool y llamamos al método func en ambos procesos con 1 y 2 como valor de argumento.

El método Process_init se utiliza para inicializar el queue_handler. La salida del código anterior es la siguiente:

salida para registro de multiprocesamiento

El código anterior muestra la información de registro de dos procesos que tienen el ID de proceso 7024 y 15680.

También podemos registrar la información en un archivo log reemplazando la declaración lg_handler = logging.StreamHandler() con lg_handler = logging.FileHandler('info.log').

El logging.FileHandler crea un archivo info.log y almacena los registros en el archivo info.log.

Artículo relacionado - Python Multiprocessing