Tarefas & JoinHandles
Tarefas Tokio são unidades leves de trabalho assíncrono agendadas no runtime. JoinHandle permite aguardar resultados, abortar a execução e rastrear a conclusão da tarefa.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
#[tokio::main]
async fn main() {
let handle = tokio::spawn(async { 42 });
let answer = handle.await.unwrap();
println!("{answer}");
}Quando usar isso: Trabalho em segundo plano, manipuladores por conexão, I/O paralelo e grupos de tarefas estruturados.
Exemplo de Trabalho
use tokio::task::JoinSet;
async fn fetch_id(id: u32) -> u32 {
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
id * 10
}
#[tokio::main]
async fn main() {
let mut set = JoinSet::new();
for id in 1..=5 {
set.spawn(fetch_id(id));
}
while let Some(res) = set.join_next().await {
println!("{}", res.unwrap());
}
}O que isso demonstra:
JoinSetgerencia tarefas dinamicamente geradas.join_nextretorna resultados à medida que as tarefas são concluídas.- O conjunto está vazio quando todas as tarefas terminam.
Mergulho Profundo
Como Funciona
- Tarefa: Futuro em caixa agendado no executor Tokio.
- JoinHandle: Handle de propriedade;
awaitretornaResult<T, JoinError>. - abort: Cancela a tarefa no próximo ponto de
await. - JoinSet / JoinMap: Coleções para muitos handles sem
Vecmanual.
Variantes de Spawn
| API | Uso |
|---|---|
tokio::spawn | Tarefas Send no runtime |
spawn_blocking | Fechamento bloqueante no pool de bloqueio |
spawn_local | !Send em LocalSet |
task::Builder | Nomeia tarefas para tracing |
Notas de Rust
// Tarefa nomeada para tokio-console / tracing
let handle = tokio::task::Builder::new()
.name("worker")
.spawn(async { /* ... */ })
.unwrap();- Sempre aguarde ou aborte handles para evitar vazamento de tarefas.
JoinErroréis_panic()ouis_cancelled().- O descarte do pai sem aguardar não cancela o filho, a menos que configurado.
Armadilhas
- Spawn "dispare e esqueça" - Erros perdidos silenciosamente. Correção: Aguarde o handle, use
JoinSetou anexe um manipulador de errostracing. - Futuro não-
Sendem spawn - Erro de compilação em runtime multi-thread. Correção:spawn_local+LocalSetou removaRc/mutex guards entreawaits. - Bloqueio dentro da tarefa gerada - Sufoca os workers. Correção:
spawn_blockingpara seções síncronas. - Crescimento ilimitado do JoinSet - Gerando mais rápido do que concluindo. Correção: Semáforo ou pool de workers com limite.
- Pânico na tarefa -
awaitretornaErr(JoinError). Correção: Corresponda ao erro; considerecatch_unwindpara isolamento.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
tokio::join! | Poucos futuros na mesma tarefa | Trabalhadores de longa duração em segundo plano |
FuturesUnordered | Não gerado; mesma tarefa | Necessita de agendamento real de SO paralelo |
| Threads do SO | Isolamento de CPU, APIs de bloqueio | Milhares de tarefas de I/O leves |
| Escopos estruturados (padrões noturnos) | Cancelamento estrito pai-filho | Spawn simples de uso único |
FAQs
Tarefa vs thread do SO?
Tarefas são agendadas cooperativamente em poucas threads - mais barato, mas não devem bloquear.
JoinHandle sem await?
A tarefa ainda é executada, mas os erros são perdidos - anti-padrão em produção.
abort vs drop?
abort cancela a tarefa gerada; descartar o handle não cancela a tarefa.
JoinSet vs Vec de handles?
JoinSet impulsiona a conclusão de forma eficiente; Vec + join manual funciona para contagens fixas pequenas.
Orçamento de tarefa?
Tokio pode ceder periodicamente - loops de CPU longos precisam de yield_now().await.
LocalSet?
Executa tarefas !Send em uma thread - testes e cenários de incorporação single-threaded.
Tarefas por requisição no Axum?
Manipuladores são tarefas; gere subtarefas para trabalho em segundo plano que sobrevive à resposta com cuidado.
Integração com tracing?
#[tracing::instrument] em async fns + tarefas nomeadas melhoram a observabilidade.
Tratamento de JoinError?
Distinga pânico vs cancelamento - o cancelamento é esperado no desligamento.
Máximo de tarefas concorrentes?
Sem limite rígido - limitado por memória e FDs; use semáforos para backpressure.
Relacionados
- Noções Básicas do Tokio - primeiro spawn
- Combinando Futures - macros join
- Cancelamento e Timeouts - abort
- Desligamento Gracioso - drenando tarefas
- Tracing e Instrumentação - tarefas nomeadas
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.