Concorrência e Multithreading em Rust: Técnicas Avançadas

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

Concorrência e Multithreading em Rust: Nível Avançado

\n\n

Concorrência e multithreading são um dos aspetos mais poderosos e, ao mesmo tempo, mais complexos da programação de sistemas. Rust oferece uma abordagem única: garantias de segurança de memória em tempo de compilação, eliminando condições de corrida (data race) e ponteiros soltos. Neste artigo, vamos explorar técnicas avançadas para trabalhar com concorrência em Rust, incluindo async/await, a biblioteca Tokio, as traits Send e Sync, e primitivas de sincronização de baixo nível.

\n\n

O material é destinado a desenvolvedores já familiarizados com os fundamentos do Rust que desejam aprofundar-se em computação paralela de alto desempenho.

\n\n

1. Modelos de Concorrência: Threads do SO e Assincronia

\n\n

Rust suporta dois modelos principais: threads do sistema operacional (OS threads) e tarefas assíncronas (async tasks). A escolha entre eles depende do cenário: para tarefas intensivas em CPU, threads são melhores; para tarefas vinculadas a I/O, o async é mais adequado.

\n\n

Threads do SO (std::thread)

\n\n

Criar uma thread em Rust é trivial, mas requer atenção à posse dos dados:

\n\n
use std::thread;\n\nlet data = vec![1, 2, 3];\n\nlet handle = thread::spawn(move || {\n    println!("{:?}", data);\n});\n\nhandle.join().unwrap();
\n\n

O ponto-chave é a palavra-chave move. Ela transfere a posse para o closure. Se precisar compartilhar dados entre threads, use Arc<Mutex<T>>.

\n\n

Programação Assíncrona (async/await)

\n\n

O código assíncrono executa dentro de uma única thread, alternando entre tarefas durante a espera por I/O. Isso reduz a sobrecarga de troca de contexto. Exemplo de uma função assíncrona simples:

\n\n
use tokio::time::{sleep, Duration};\n\n#[tokio::main]\nasync fn main() {\n    let task1 = async_task("Tarefa 1");\n    let task2 = async_task("Tarefa 2");\n\n    tokio::join!(task1, task2);\n}\n\nasync fn async_task(name: &str) {\n    println!("{} iniciada", name);\n    sleep(Duration::from_secs(1)).await;\n    println!("{} concluída", name);\n}
\n\n

A biblioteca tokio é o padrão para Rust assíncrono. Ela fornece um escalonador multithread (work-stealing scheduler) que distribui tarefas eficientemente entre os núcleos da CPU.

\n\n

2. Traits Send e Sync: Segurança na Concorrência

\n\n

Duas traits-chave garantem a segurança da concorrência em Rust:

\n\n
    \n
  • Send — um tipo pode ser transferido com segurança entre threads.
  • \n
  • Sync — um tipo pode ser referenciado com segurança por várias threads simultaneamente.
  • \n
\n\n

A maioria dos primitivos do Rust implementa automaticamente essas traits se seus componentes as implementarem. Por exemplo, Arc<Mutex<i32>> é Send e Sync, enquanto Rc<RefCell<i32>> não é.

\n\n

Vejamos um exemplo que não compila devido a uma violação de Send:

\n\n
use std::rc::Rc;\nuse std::thread;\n\nlet data = Rc::new(5);\n\nthread::spawn(move || {\n    println!("{}", data);\n}); // Erro: Rc<i32> não implementa Send
\n\n

O compilador Rust emitirá uma mensagem de erro clara, prevenindo condições de corrida em tempo de compilação. Esta é uma das principais vantagens da linguagem.

\n\n

3. Sincronização Avançada: Canais, Mutexes e RwLock

\n\n

Para troca de dados entre threads, Rust oferece vários primitivos. Vamos explorar os mais poderosos.

\n\n

Canais (mpsc)

\n\n

Canais multithread (multi-producer, single-consumer) permitem enviar mensagens de várias threads para um único recetor:

\n\n
use std::sync::mpsc;\nuse std::thread;\n\nlet (tx, rx) = mpsc::channel();\n\nfor i in 0..3 {\n    let tx_clone = tx.clone();\n    thread::spawn(move || {\n        tx_clone.send(i).unwrap();\n    });\n}\n\ndrop(tx); // Fechamos o transmissor\n\nfor received in rx {\n    println!("Recebido: {}", received);\n}
\n\n

Canais são ideais para arquiteturas do tipo "produtor

Blogs

Book Recommendations