0Pricing
Python Academy · Lección

ThreadPoolExecutor

Ejecute tareas simultáneamente

ThreadPoolExecutor es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Python Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Python Academy incluye 4 lecciones en total.

¿Por qué utilizar un grupo de hilos?

Crear y unir hilos manualmente resulta tedioso. concurrent.futures.ThreadPoolExecutor administra por usted un grupo de hilos trabajadores y devuelve los resultados de forma sencilla.

from concurrent.futures import ThreadPoolExecutor

def square(n):
    return n * n

with ThreadPoolExecutor() as ex:
    future = ex.submit(square, 5)
    print(future.result())

submit y Future

submit() programa una llamada y devuelve inmediatamente un Future. Llame a .result() para obtener el valor; la llamada se bloqueará hasta que esté disponible.

from concurrent.futures import ThreadPoolExecutor

def greet(name):
    return 'hi ' + name

with ThreadPoolExecutor(max_workers=2) as ex:
    f1 = ex.submit(greet, 'Ana')
    f2 = ex.submit(greet, 'Bob')
    print(f1.result())
    print(f2.result())

map para varias entradas

executor.map(func, iterable) ejecuta la función de forma concurrente para cada elemento y produce los resultados en el orden de entrada.

from concurrent.futures import ThreadPoolExecutor

def cube(n):
    return n ** 3

with ThreadPoolExecutor() as ex:
    results = ex.map(cube, range(5))
    print(list(results))

Controlar el número de trabajadores

max_workers limita cuántos hilos se ejecutan a la vez. Para trabajos limitados por E/S, puede utilizar más trabajadores que núcleos de CPU.

from concurrent.futures import ThreadPoolExecutor
import time

def io_task(n):
    time.sleep(0.05)
    return n

start = time.perf_counter()
with ThreadPoolExecutor(max_workers=4) as ex:
    print(list(ex.map(io_task, range(4))))
print('ran concurrently')

as_completed

as_completed(futures) produce cada future en el momento en que termina, independientemente del orden en que se envió. Es ideal para procesar los resultados en cuanto llegan.

from concurrent.futures import ThreadPoolExecutor, as_completed
import time

def work(n):
    time.sleep(0.01 * (3 - n))
    return n

with ThreadPoolExecutor() as ex:
    futures = [ex.submit(work, i) for i in range(3)]
    for f in as_completed(futures):
        print('finished', f.result())

Gestionar excepciones

Si una tarea genera una excepción, esta se almacena en su Future y vuelve a generarse al llamar a .result(). Incluya esa llamada en un bloque try/except.

from concurrent.futures import ThreadPoolExecutor

def risky(n):
    if n == 0:
        raise ValueError('cannot be zero')
    return 10 // n

with ThreadPoolExecutor() as ex:
    f = ex.submit(risky, 0)
    try:
        print(f.result())
    except ValueError as e:
        print('caught:', e)

Mapear con varios argumentos

map acepta varios iterables y los combina como argumentos, igual que la función integrada map.

from concurrent.futures import ThreadPoolExecutor

def add(a, b):
    return a + b

with ThreadPoolExecutor() as ex:
    print(list(ex.map(add, [1, 2, 3], [10, 20, 30])))

Recopilar resultados en un diccionario

Un patrón habitual consiste en asociar cada future con su entrada para saber qué resultado corresponde a cada elemento al utilizar as_completed.

from concurrent.futures import ThreadPoolExecutor, as_completed

def length(word):
    return len(word)

words = ['cat', 'tiger', 'ox']
with ThreadPoolExecutor() as ex:
    future_to_word = {ex.submit(length, w): w for w in words}
    out = {}
    for f in as_completed(future_to_word):
        out[future_to_word[f]] = f.result()
print(sorted(out.items()))

Cierre mediante un gestor de contexto

Al utilizar el executor dentro de un bloque with, se llama automáticamente a shutdown() y se espera a que terminen todas las tareas pendientes.

from concurrent.futures import ThreadPoolExecutor

def job(n):
    return n * 2

with ThreadPoolExecutor() as ex:
    futures = [ex.submit(job, i) for i in range(3)]
print('all tasks done after the with block')
print([f.result() for f in futures])

Comprobar el estado de un Future

Un Future ofrece .done() y .running(), que permiten inspeccionar el progreso sin bloquear la ejecución.

from concurrent.futures import ThreadPoolExecutor

def quick(n):
    return n + 1

with ThreadPoolExecutor() as ex:
    f = ex.submit(quick, 41)
    result = f.result()
    print('done?', f.done())
    print('value:', result)

Cuándo utilizarlo

ThreadPoolExecutor es ideal para muchas tareas pequeñas limitadas por E/S: llamadas HTTP, lecturas de archivos y consultas a bases de datos. Para trabajos limitados por CPU, utilice ProcessPoolExecutor.

from concurrent.futures import ThreadPoolExecutor

urls = ['a', 'b', 'c']

def fetch(u):
    return 'fetched ' + u

with ThreadPoolExecutor(max_workers=3) as ex:
    for r in ex.map(fetch, urls):
        print(r)

Comprobación rápida

Compruebe su comprensión de ThreadPoolExecutor.

Resumen

Ha aprendido ThreadPoolExecutor:

  • submit() devuelve un Future; map() recorre un iterable en orden.
  • as_completed() proporciona los futuros a medida que terminan.
  • Las excepciones se manifiestan mediante result().
  • El bloque with gestiona el apagado.

A continuación: paralelismo real con multiprocessing.

Preguntas frecuentes

¿La lección «ThreadPoolExecutor» es gratis?

Sí — el texto completo de «ThreadPoolExecutor» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Python Academy, actualiza a CoddyKit PRO. El curso de Python Academy incluye 4 lecciones en total.

¿Qué aprenderé en «ThreadPoolExecutor»?

Ejecute tareas simultáneamente Practicas Python Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Python Academy?

No se requiere experiencia previa. Python Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «ThreadPoolExecutor»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Python Academy?

Sí. Cada lección de Python Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Hilos y el GIL
  2. ThreadPoolExecutor
  3. Conceptos básicos de multiprocessing
  4. Uso seguro de datos compartidos
← Volver a Python Academy