Multiprocesamiento en Python | Serie 1 (Introducción)

Este artículo es una introducción breve pero concisa al multiprocesamiento en el lenguaje de programación Python.

¿Qué es el multiprocesamiento?

El multiprocesamiento se refiere a la capacidad de un sistema para admitir más de un procesador al mismo tiempo. Las aplicaciones en un sistema de multiprocesamiento se dividen en rutinas más pequeñas que se ejecutan de forma independiente. El sistema operativo asigna estos hilos a los procesadores mejorando el rendimiento del sistema.

¿Por qué multiprocesamiento?

Considere un sistema informático con un solo procesador. Si se le asignan varios procesos al mismo tiempo, tendrá que interrumpir cada tarea y cambiar brevemente a otra para mantener todos los procesos en marcha.
Esta situación es como un chef que trabaja solo en una cocina. Tiene que hacer varias tareas como hornear, remover, amasar, etc.

Entonces, la esencia es que: Cuantas más tareas deba hacer a la vez, más difícil se vuelve hacer un seguimiento de todas ellas, y mantener el tiempo correcto se convierte en un desafío mayor.
¡Aquí es donde surge el concepto de multiprocesamiento!
Un sistema multiprocesador puede tener:

  • multiprocesador, es decir, una computadora con más de un procesador central.
  • Procesador multinúcleo, es decir, un solo componente informático con dos o más unidades de procesamiento reales independientes (llamadas «núcleos»).

Aquí, la CPU puede ejecutar fácilmente varias tareas a la vez, y cada tarea utiliza su propio procesador.

Es como el chef en la última situación siendo asistido por sus asistentes. Ahora, pueden dividir las tareas entre ellos y el chef no necesita cambiar entre sus tareas.

Multiprocesamiento en Python

En Python, el módulo de multiprocesamiento incluye una API muy simple e intuitiva para dividir el trabajo entre múltiples procesos.
Consideremos un ejemplo simple usando un módulo de multiprocesamiento:

# importing the multiprocessing module
import multiprocessing
  
def print_cube(num):
    """
    function to print cube of given num
    """
    print("Cube: {}".format(num * num * num))
  
def print_square(num):
    """
    function to print square of given num
    """
    print("Square: {}".format(num * num))
  
if __name__ == "__main__":
    # creating processes
    p1 = multiprocessing.Process(target=print_square, args=(10, ))
    p2 = multiprocessing.Process(target=print_cube, args=(10, ))
  
    # starting process 1
    p1.start()
    # starting process 2
    p2.start()
  
    # wait until process 1 is finished
    p1.join()
    # wait until process 2 is finished
    p2.join()
  
    # both processes finished
    print("Done!")
Square: 100
Cube: 1000
Done!

Tratemos de entender el código anterior:

  • Para importar el módulo de multiprocesamiento, hacemos:
    import multiprocessing
    
  • Para crear un proceso, creamos un objeto de la clase Proceso . Toma los siguientes argumentos:
    • target : la función a ser ejecutada por el proceso
    • args : los argumentos que se pasarán a la función de destino

    Nota: El constructor de procesos también toma muchos otros argumentos que se discutirán más adelante. En el ejemplo anterior, creamos 2 procesos con diferentes funciones objetivo:

    p1 = multiprocessing.Process(target=print_square, args=(10, ))
    p2 = multiprocessing.Process(target=print_cube, args=(10, ))
    
  • Para iniciar un proceso, usamos el método de inicio de la clase Process .
    p1.start()
    p2.start()
    
  • Una vez que se inician los procesos, el programa actual también sigue ejecutándose. Para detener la ejecución del programa actual hasta que se complete un proceso, usamos el método de unión .
    p1.join()
    p2.join()
    

    Como resultado, el programa actual primero esperará a que se complete p1 y luego p2 . Una vez que se completan, se ejecutan las siguientes declaraciones del programa actual.

Consideremos otro programa para comprender el concepto de diferentes procesos que se ejecutan en el mismo script de python. En este ejemplo a continuación, imprimimos la ID de los procesos que ejecutan las funciones de destino:

# importing the multiprocessing module
import multiprocessing
import os
  
def worker1():
    # printing process id
    print("ID of process running worker1: {}".format(os.getpid()))
  
def worker2():
    # printing process id
    print("ID of process running worker2: {}".format(os.getpid()))
  
if __name__ == "__main__":
    # printing main program process id
    print("ID of main process: {}".format(os.getpid()))
  
    # creating processes
    p1 = multiprocessing.Process(target=worker1)
    p2 = multiprocessing.Process(target=worker2)
  
    # starting processes
    p1.start()
    p2.start()
  
    # process IDs
    print("ID of process p1: {}".format(p1.pid))
    print("ID of process p2: {}".format(p2.pid))
  
    # wait until processes are finished
    p1.join()
    p2.join()
  
    # both processes finished
    print("Both processes finished execution!")
  
    # check if processes are alive
    print("Process p1 is alive: {}".format(p1.is_alive()))
    print("Process p2 is alive: {}".format(p2.is_alive()))
ID of main process: 28628
ID of process running worker1: 29305
ID of process running worker2: 29306
ID of process p1: 29305
ID of process p2: 29306
Both processes finished execution!
Process p1 is alive: False
Process p2 is alive: False
  • El script principal de Python tiene una ID de proceso diferente y el módulo de multiprocesamiento genera nuevos procesos con diferentes ID de proceso a medida que creamos los objetos Process p1 y p2 . En el programa anterior, usamos la función os.getpid() para obtener la ID del proceso que ejecuta la función de destino actual.

    Observe que coincide con los ID de proceso de p1 y p2 que obtenemos usando el atributo pid de la clase Process .

  • Cada proceso se ejecuta de forma independiente y tiene su propio espacio de memoria.
  • Tan pronto como finaliza la ejecución de la función de destino, los procesos finalizan. En el programa anterior, usamos el método is_alive de la clase Process para verificar si un proceso aún está activo o no.

Considere el siguiente diagrama para comprender cómo los nuevos procesos son diferentes del script principal de Python:

Por lo tanto, esta fue una breve introducción al multiprocesamiento en Python. Los siguientes artículos cubrirán los siguientes temas relacionados con el multiprocesamiento:

  • Compartir datos entre procesos usando Array, valor y colas.
  • Conceptos de Lock y Pool en multiprocesamiento

Próximo:

Referencias:

Este artículo es una contribución de Nikhil Kumar . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *