ThreadPoolExecutor
Eseguire attività in concorrenza
ThreadPoolExecutor è una lezione Python Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Python Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Python Academy include 4 lezioni in totale.
Perché usare un thread pool?
Creare e unire i thread manualmente è tedioso. concurrent.futures.ThreadPoolExecutor gestisce per Lei un pool di thread worker e restituisce i risultati in modo ordinato.
from concurrent.futures import ThreadPoolExecutor
def square(n):
return n * n
with ThreadPoolExecutor() as ex:
future = ex.submit(square, 5)
print(future.result())submit e Future
submit() pianifica una chiamata e restituisce immediatamente un Future. Lo utilizza con .result() per ottenere il valore, bloccando l'esecuzione finché non è pronto.
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 per molti input
executor.map(func, iterable) esegue la funzione su ogni elemento in concorrenza e produce i risultati nell'ordine degli input.
from concurrent.futures import ThreadPoolExecutor
def cube(n):
return n ** 3
with ThreadPoolExecutor() as ex:
results = ex.map(cube, range(5))
print(list(results))Controllare il numero di worker
max_workers limita il numero di thread eseguiti contemporaneamente. Per il lavoro I/O-bound può usare più worker del numero di core della 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 ogni future non appena termina, indipendentemente dall'ordine di invio. È ideale per elaborare i risultati non appena arrivano.
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())Gestire le eccezioni
Se un'attività genera un'eccezione, questa viene memorizzata nel relativo Future e generata nuovamente quando chiama .result(). Racchiuda la chiamata in un blocco 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)Eseguire il mapping con più argomenti
map accetta diversi iterabili e li combina come argomenti, proprio come il built-in 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])))Raccogliere i risultati in un dizionario
Un modello comune associa ogni future al relativo input, così può sapere a quale input corrisponde ciascun risultato quando usa 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()))Arresto con il context manager
Usare l'executor in un blocco with chiama automaticamente shutdown(), attendendo il completamento di tutte le attività in sospeso.
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])Controllare lo stato di un Future
Un Future espone .done() e .running(), così può controllare lo stato di avanzamento senza bloccare l'esecuzione.
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)Quando usarlo
ThreadPoolExecutor è ideale per molte piccole attività I/O-bound: chiamate HTTP, letture di file e query al database. Per il lavoro CPU-bound, usi invece 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)Verifica rapida
Verifichi la Sua comprensione di ThreadPoolExecutor.
Ripasso
Ha imparato a usare ThreadPoolExecutor:
submit()restituisce un Future;map()opera su un iterabile mantenendone l'ordine.as_completed()restituisce i future man mano che terminano.- Le eccezioni vengono rese disponibili tramite
result(). - Il blocco
withgestisce l'arresto.
Avanti: il vero parallelismo con multiprocessing.
Domande Frequenti
La lezione «ThreadPoolExecutor» è gratuita?
Sì — il testo completo di «ThreadPoolExecutor» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Python Academy, passa a CoddyKit PRO. Il corso Python Academy include 4 lezioni in totale.
Cosa imparerò in «ThreadPoolExecutor»?
Eseguire attività in concorrenza Eserciti Python Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Python Academy?
Non è richiesta alcuna esperienza precedente. Python Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «ThreadPoolExecutor»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Python Academy?
Sì. Ogni lezione Python Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.