0Pricing
Python Academy · Aula

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 with cuida 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.

Todas as aulas deste curso

  1. Threads e o GIL
  2. ThreadPoolExecutor
  3. Noções básicas de multiprocessing
  4. Compartilhamento seguro de dados
← Voltar para Python Academy