parking_lot para Rust: primitivas de sincronização rápidas
A biblioteca parking_lot é uma das implementações mais populares e eficientes de primitivas de sincronização para a linguagem Rust. Ela oferece uma alternativa aos mutexes padrão (std::sync::Mutex), bloqueios de leitura-escrita (std::sync::RwLock) e variáveis de condição (std::sync::Condvar), mas com desempenho significativamente superior e menor consumo de código.
Por que usar esta biblioteca? As primitivas de sincronização padrão do Rust, embora seguras, têm algumas desvantagens: elas usam chamadas de sistema (futex no Linux) mesmo em cenários simples, exigem memória extra para flags e têm uma implementação interna mais complexa. O parking_lot resolve esses problemas usando algoritmos mais eficientes (como bloqueios otimistas e spin-loops) e minimizando a sobrecarga. Como resultado, o código roda mais rápido, especialmente em aplicações multithread com alta contenção.
A biblioteca é totalmente compatível com Rust e não requer código unsafe por parte do usuário. Ela oferece as mesmas interfaces que a biblioteca padrão, mas com recursos adicionais: Mutex com suporte a timeouts, RwLock com fila justa, Once para inicialização lazy e ReentrantMutex para bloqueios reentrantes. O parking_lot é o padrão de facto para aplicações Rust de alto desempenho, desde servidores web até motores de jogos.
Instalação
Adicione a biblioteca ao arquivo Cargo.toml do seu projeto:
[dependencies]
parking_lot = "0.12"
Em seguida, execute o comando:
cargo build
Ou, se você usa cargo add (a partir do Rust 1.62):
cargo add parking_lot
Depois disso, você pode importar as primitivas da biblioteca:
use parking_lot::{Mutex, RwLock, Condvar, Once, ReentrantMutex};
Início rápido: exemplo mínimo funcional
Aqui está um exemplo simples de uso do Mutex do parking_lot para proteger um contador compartilhado em um ambiente multithread:
use parking_lot::Mutex;
use std::thread;
fn main() {
// Cria um mutex envolvendo o valor
let counter = Mutex::new(0);
// Cria 10 threads, cada uma incrementa o contador em 1
let mut handles = vec![];
for _ in 0..10 {
let handle = thread::spawn(|| {
// Adquire o bloqueio — .lock() retorna um RAII guard
let mut guard = counter.lock();
*guard += 1;
// guard é liberado automaticamente ao sair do escopo
});
handles.push(handle);
}
// Aguarda a conclusão de todas as threads
for handle in handles {
handle.join().unwrap();
}
// Lê o valor final
let final_value = *counter.lock();
println!("Valor final: {}", final_value); // Deve ser 10
}
Neste exemplo, counter.lock() retorna um MutexGuard, que libera automaticamente o bloqueio ao ser destruído. Ao contrário do std::sync::Mutex padrão, não é necessário tratar erros de poisoning — o parking_lot não envenena o mutex em caso de pânico por padrão.
Métodos e tipos principais
Abaixo estão 8 métodos/tipos principais da biblioteca parking_lot com assinaturas, descrições e exemplos.
1. Mutex::lock()
Assinatura: pub fn lock(&self) -> MutexGuard<'_, T>
Descrição: Adquire o mutex, bloqueando a thread atual até que o bloqueio seja obtido. Retorna um RAII guard que libera automaticamente o bloqueio ao sair do escopo.
use pa Também na biblioteca
libcurl para C++: guia completo com exemplos
Processamento de Imagens em Kotlin: redimensionar e cortar com a biblioteca ImageMagick