ThreadPoolExecutor
Execute tarefas simultaneamente
ThreadPoolExecutor é uma aula grátis de Python Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Python Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Python Academy inclui 4 aulas no total.
Por que usar um conjunto de encadeamentos
Criar e unir encadeamentos manualmente é trabalhoso. concurrent.futures.ThreadPoolExecutor gerencia um conjunto de encadeamentos de trabalho para você e retorna resultados de forma organizada.
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 futuro
submit() agenda uma chamada e retorna imediatamente um futuro. Você chama .result() nele para obter o valor, bloqueando até que esteja 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 para várias entradas
executor.map(func, iterable) executa a função sobre cada item concorrentemente e produz os resultados na ordem das entradas.
from concurrent.futures import ThreadPoolExecutor
def cube(n):
return n ** 3
with ThreadPoolExecutor() as ex:
results = ex.map(cube, range(5))
print(list(results))Controlando a quantidade de trabalhadores
max_workers limita quantos encadeamentos são executados ao mesmo tempo. Para trabalhos limitados por E/S, você pode usar mais trabalhadores do que o número de núcleos da 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) produz cada futuro assim que ele termina, independentemente da ordem de envio. É excelente para processar resultados assim que chegam.
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())Tratando exceções
Se uma tarefa gerar uma exceção, ela será armazenada em seu futuro e gerada novamente quando você chamar .result(). Envolva essa chamada em 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)Mapeando com vários argumentos
map aceita vários iteráveis e os combina como argumentos, assim como a função 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])))Coletando resultados em um dicionário
Um padrão comum associa cada futuro à sua entrada para que você saiba qual resultado corresponde a qual entrada ao usar 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()))Encerramento pelo gerenciador de contexto
Usar o executor em um bloco with chama shutdown() automaticamente, aguardando a conclusão de todas as tarefas pendentes.
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])Verificando o estado de um futuro
Um futuro disponibiliza .done() e .running(), para que você possa verificar o progresso sem bloquear.
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 usar
ThreadPoolExecutor é ideal para muitas tarefas pequenas limitadas por E/S: chamadas HTTP, leituras de arquivos e consultas ao banco de dados. Para trabalhos limitados pela CPU, use 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ção rápida
Teste sua compreensão de ThreadPoolExecutor.
Recapitulação
Você aprendeu a usar ThreadPoolExecutor:
submit()retorna um resultado futuro;map()percorre um iterável na ordem.as_completed()produz resultados futuros à medida que são concluídos.- As exceções são propagadas por
result(). - O bloco
withcuida do encerramento.
A seguir: paralelismo verdadeiro com multiprocessamento.
Perguntas Frequentes
A aula “ThreadPoolExecutor” é grátis?
Sim — o texto completo de “ThreadPoolExecutor” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Python Academy, atualize para CoddyKit PRO. O curso de Python Academy inclui 4 aulas no total.
O que vou aprender em “ThreadPoolExecutor”?
Execute tarefas simultaneamente Você pratica Python Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Python Academy?
Nenhuma experiência prévia é necessária. Python Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “ThreadPoolExecutor”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Python Academy?
Sim. Cada aula de Python Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.