Programação Assíncrona em Rust: guia completo com exemplos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Programação Assíncrona em Rust: do Básico às Técnicas Avançadas



Aplicações modernas exigem alta performance e operações de I/O eficientes. Rust, conhecido por sua velocidade e segurança, oferece um poderoso modelo de programação assíncrona. Neste guia, vamos detalhar como usar async/await, a biblioteca tokio e outras ferramentas para criar programas assíncronos rápidos e confiáveis.



O que é Programação Assíncrona em Rust?



Programação assíncrona é um paradigma que permite executar múltiplas tarefas simultaneamente sem criar threads do SO. Em vez de bloquear uma thread ao aguardar I/O (leitura de arquivo, requisição HTTP), uma função assíncrona "pausa" e transfere o controle para outras tarefas. Rust implementa isso através de Futures e do mecanismo async/await.



Conceitos-chave:

  • Future — uma trait que representa uma operação assíncrona que pode ser concluída mais tarde.
  • async/await — açúcar sintático para trabalhar com Futures.
  • Runtime (executor) — o ambiente de execução que polla as Futures e as executa. O mais popular é o Tokio.
  • Task — uma unidade de trabalho leve, gerenciada pelo Runtime.


Primeiro Programa Assíncrono em Rust



Para começar, adicione as dependências no Cargo.toml:



[dependencies]tokio = { version = "1", features = ["full"] }reqwest = { version = "0.12", features = ["json"] }serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"


Agora vamos escrever um cliente HTTP assíncrono simples:



use reqwest;use serde::Deserialize;

#[derive(Deserialize, Debug)]struct Todo { userId: u32, id: u32, title: String, completed: bool,}

#[tokio::main]async fn main() -> Result<(), Box> { // Requisição GET assíncrona let response = reqwest::get("https://jsonplaceholder.typicode.com/todos/1") .await?; // await pausa a execução até a resposta chegar let todo: Todo = response.json().await?; // Desserialização assíncrona println!("Tarefa recebida: {:#?}", todo); Ok(())}


Observe a macro #[tokio::main] — ela transforma a função main comum em um ponto de entrada assíncrono, iniciando o Runtime do Tokio.



Criando Funções Assíncronas e Trabalhando com Tarefas



Você pode criar suas próprias funções assíncronas usando a palavra-chave async fn:



use std::time::Duration;use tokio::time::sleep;

async fn simulate_work(id: u32, duration_secs: u64) -> String { println!("Tarefa {} iniciada", id); sleep(Duration::from_secs(duration_secs)).await; // Atraso assíncrono println!("Tarefa {} concluída", id); format!("Resultado da tarefa {}", id)}

#[tokio::main]async fn main() { let start = std::time::Instant::now(); // Criando tarefas assíncronas (tasks) let task1 = tokio::spawn(simulate_work(1, 2)); let task2 = tokio::spawn(simulate_work(2, 1)); let task3 = tokio::spawn(simulate_work(3, 3)); // Aguardando a conclusão de todas as tarefas let results = tokio::join!(task1, task2, task3); // Processando os resultados for result in &results { match result { Ok(msg) => println!("{}", msg), Err(e) => eprintln!("Erro: {}", e), } } println!("Tempo total: {:?}", start.elapsed()); // Será executado em ~3 segundos, não em 6!}


A função tokio::spawn cria uma tarefa assíncrona independente que é executada em paralelo com outras. tokio::join! aguarda a conclusão de todos os futures passados.



Técnicas Avançadas

Blogs

Book Recommendations