Introducción al multihilo y multiprocesamiento en Python
Al desarrollar aplicaciones modernas, a menudo se necesita mejorar el rendimiento. Esto se logra mediante la ejecución paralela de tareas. En Python, para ello se utilizan herramientas como el multihilo y el multiprocesamiento. A pesar del bloqueo global del intérprete (GIL), el multihilo en Python puede acelerar significativamente los programas. Esto es especialmente relevante para tareas relacionadas con entrada/salida (I/O), como solicitudes de red o trabajo con archivos.
En esta guía, analizaremos cómo funciona el multihilo en Python. Exploraremos la librería threading, la compararemos con multiprocessing y proporcionaremos ejemplos prácticos. Esto te ayudará a entender cómo optimizar tu código para acelerar su ejecución.
¿Qué es el multihilo en Python?
El multihilo en Python permite ejecutar varios hilos (threads) dentro de un mismo proceso. Cada hilo ejecuta una parte del código en paralelo. Este enfoque es eficaz para tareas donde se esperan recursos externos.
Ventajas del multihilo para tareas de entrada/salida
El multihilo acelera los programas cuando las tareas incluyen:
- Solicitudes de red, como la descarga de datos de internet.
- Trabajo con archivos, incluyendo lectura y escritura.
- Acceso a bases de datos.
- Otras operaciones de entrada/salida donde la CPU está inactiva en espera.
Sin embargo, el multihilo tiene limitaciones. En Python existe el bloqueo global del intérprete (GIL). El GIL impide la ejecución simultánea de bytecode de Python en múltiples hilos. Debido a esto, el multihilo no es adecuado para tareas con uso intensivo de CPU, donde se requiere una carga completa del procesador.
¿Cuándo usar multihilo o multiprocesamiento?
La elección entre multihilo y multiprocesamiento depende del tipo de tareas. El multihilo es adecuado para escenarios con espera, mientras que el multiprocesamiento lo es para cálculos.
Recomendaciones según el escenario
- Tareas con gran volumen de entrada/salida: Usa threading (hilos) para evitar bloquear el hilo principal.
- Tareas computacionalmente intensivas: Aplica multiprocessing (procesos) para evitar el GIL y aprovechar varios núcleos de la CPU.
- Trabajo con APIs de red: Elige threading para un manejo eficiente de las solicitudes.
- Procesamiento paralelo de datos: Es óptimo usar multiprocessing para distribuir la carga entre los procesadores.
Este enfoque ayuda a evitar el uso ineficiente de los recursos y acelera la ejecución del programa.
La librería threading: fundamentos y ejemplos
La librería threading en Python proporciona herramientas para crear y gestionar hilos. Es fácil de usar y adecuada para principiantes.
Ejemplo simple de creación de un hilo
Aquí tienes un ejemplo básico de multihilo en Python:
import threading
import time
def print_numbers():
for i in range(5):
print(f"Número: {i}")
time.sleep(1)
# Creamos un hilo
thread = threading.Thread(target=print_numbers)
thread.start()
# El hilo principal continúa
print("¡Hilo principal finalizado!")
En este código, el hilo principal finaliza inmediatamente, mientras que la función print_numbers se ejecuta en un hilo separado. Esto demuestra cómo el multihilo permite continuar el trabajo sin esperar.
Pasar argumentos a un hilo
Para pasar datos a la función de un hilo, usa el parámetro args:
def greet(name):
print(f"¡Hola, {name}!")
thread = threading.Thread(target=greet, args=("Carlos",))
thread.start()
Aquí, el argumento "Carlos" se pasa a la función greet. Esto es útil para parametrizar tareas en los hilos.
Esperar a que los hilos terminen con join
El método join permite esperar a que un hilo termine su ejecución.