Ejecución paralela con multiprocesamiento de Python

PythonPythonIntermediate
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Python multiprocessing es una herramienta poderosa que puede acelerar significativamente la ejecución de programas de Python que requieren gran capacidad de procesamiento. En este laboratorio, aprenderá sobre Python multiprocessing y cómo utilizarlo para ejecutar procesos en paralelo. Empezaremos con ejemplos simples y luego iremos hacia ejemplos más complejos.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/ModulesandPackagesGroup(["Modules and Packages"]) python(("Python")) -.-> python/FileHandlingGroup(["File Handling"]) python(("Python")) -.-> python/AdvancedTopicsGroup(["Advanced Topics"]) python/BasicConceptsGroup -.-> python/numeric_types("Numeric Types") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/ModulesandPackagesGroup -.-> python/standard_libraries("Common Standard Libraries") python/FileHandlingGroup -.-> python/with_statement("Using with Statement") python/AdvancedTopicsGroup -.-> python/threading_multiprocessing("Multithreading and Multiprocessing") python/PythonStandardLibraryGroup -.-> python/os_system("Operating System and System") subgraph Lab Skills python/numeric_types -.-> lab-7843{{"Ejecución paralela con multiprocesamiento de Python"}} python/function_definition -.-> lab-7843{{"Ejecución paralela con multiprocesamiento de Python"}} python/standard_libraries -.-> lab-7843{{"Ejecución paralela con multiprocesamiento de Python"}} python/with_statement -.-> lab-7843{{"Ejecución paralela con multiprocesamiento de Python"}} python/threading_multiprocessing -.-> lab-7843{{"Ejecución paralela con multiprocesamiento de Python"}} python/os_system -.-> lab-7843{{"Ejecución paralela con multiprocesamiento de Python"}} end

Creando un programa simple de multiprocesamiento

El primer paso para aprender sobre el multiprocesamiento en Python es crear un programa simple que demuestre cómo funciona. En este programa, crearemos una función que tome un solo argumento y devuelva el cuadrado de ese número. Luego usaremos el multiprocesamiento para ejecutar esta función en múltiples procesos.

Complete square.py.

import multiprocessing

def square(x):
    return x * x

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=4)
    results = pool.map(square, range(10))
    print(results)

Este código crea un grupo de cuatro procesos y utiliza la función map() para aplicar la función square() a cada uno de los números en el rango de 0 a 9. Los resultados se imprimen luego en la consola.

Usando el multiprocesamiento para acelerar el procesamiento

Ahora que ya entiendes cómo funciona el multiprocesamiento en Python, podemos pasar a un ejemplo más complejo. En este ejemplo, usaremos el multiprocesamiento para acelerar el procesamiento de una gran lista de números.

Complete complex_square.py.

import multiprocessing

def square(x):
    return x * x

if __name__ == '__main__':
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(square, range(1000000))
    print(results[:10])

Este código crea un grupo de cuatro procesos y utiliza la función map() para aplicar la función square() a cada uno de los números en el rango de 0 a 999999. La declaración with se utiliza para garantizar que el grupo de procesos se cierre correctamente una vez que se complete el procesamiento. Los primeros diez resultados se imprimen luego en la consola.

Comunicación entre procesos

En algunos casos, es posible que necesites comunicar entre procesos al utilizar el multiprocesamiento en Python. En este ejemplo, usaremos la función multiprocessing.Queue() para crear una cola compartida entre procesos.

Complete multiprocessing_queue.py.

import multiprocessing

def producer(queue):
    for i in range(10):
        queue.put(i)

def consumer(queue):
    while True:
        item = queue.get()
        if item is None:
            break
        print(item)

if __name__ == '__main__':
    queue = multiprocessing.Queue()
    process_producer = multiprocessing.Process(target=producer, args=(queue,))
    process_consumer = multiprocessing.Process(target=consumer, args=(queue,))
    process_producer.start()
    process_consumer.start()
    process_producer.join()
    queue.put(None)
    process_consumer.join()

Este código crea una cola compartida queue utilizando la función multiprocessing.Queue(). Luego creamos dos procesos que cada uno llama a una función producer() y consumer(). La función producer() coloca los números del 0 al 9 en la cola, mientras que la función consumer() obtiene cada elemento de la cola y lo imprime en la consola.

Tareas asíncronas con Pool.apply_async()

Además de map(), la clase multiprocessing.Pool() proporciona otro método para ejecutar procesos en paralelo llamado apply_async(). Este método te permite enviar una llamada de función a un grupo de procesos y continuar la ejecución inmediatamente sin esperar por el resultado. En cambio, puedes usar una función de devolución de llamada para recuperar el resultado de la llamada de función cuando esté listo.

Complete slow_square.py.

import multiprocessing
import time

def slow_square(x):
    time.sleep(1)
    return x * x

def callback(result):
    print(result)

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=4)
    results = [pool.apply_async(slow_square, (x,), callback=callback) for x in range(10)]
    for result in results:
        result.wait()
    print("All tasks completed.")

En este ejemplo, definimos una función slow_square() que toma un número x, espera un segundo y luego devuelve el cuadrado de x. También definimos una función de devolución de llamada callback() que simplemente imprime el resultado cuando esté disponible.

Luego creamos un grupo de cuatro procesos y usamos apply_async() para enviar una llamada de función al grupo para cada número en el rango de 0 a 9. Pasamos la función slow_square() y el argumento x usando el parámetro args, y también especificamos la función de devolución de llamada que se llamará cuando el resultado esté listo.

Luego recorremos la lista de resultados y llamamos a result.wait() para bloquear el hilo principal hasta que el resultado esté listo. Finalmente, imprimimos un mensaje para indicar que todas las tareas se han completado.

Resumen

En este laboratorio, aprendiste cómo usar el multiprocesamiento de Python para ejecutar procesos en paralelo. Comenzaste con un programa simple que demostró cómo funciona el multiprocesamiento, y luego pasaste a ejemplos más complejos que usan el multiprocesamiento para acelerar el procesamiento, compartir memoria entre procesos y realizar tareas asíncronas usando apply_async(). Al final de este laboratorio, deberías tener una buena comprensión de cómo usar el multiprocesamiento en tus propios programas de Python para lograr una mayor potencia y eficiencia de procesamiento, y para comunicarte entre procesos cuando sea necesario.