No description
Find a file
2026-09-01 13:05:07 +02:00
.woodpecker chore: migrate CI to .woodpecker/{push,branch}.yml 2026-09-01 13:05:07 +02:00
src initial content 2026-09-01 13:05:03 +02:00
tests initial content 2026-09-01 13:05:03 +02:00
.gitignore Initial commit 2026-09-01 11:04:28 +00:00
Cargo.lock initial content 2026-09-01 13:05:03 +02:00
Cargo.toml chore: declare MSRV 1.85 (edition 2024) 2026-09-01 13:05:07 +02:00
LICENSE chore: add AGPL-3.0 license and standard .gitignore 2026-09-01 13:05:06 +02:00
README.md initial content 2026-09-01 13:05:03 +02:00

Lição 43: Shared State — Mutex e Arc (Cofre Compartilhado)

1. Narrativa

O mecha Æther possui um cofre central de energia que deve ser acessado por múltiplos subsistemas simultaneamente. Sem controle, dois braços poderiam tentar drenar energia ao mesmo tempo, causando sobrecarga. O Mutex é a fechadura do cofre — garante que apenas um sistema por vez acesse o recurso. O Arc é a cópia da chave replicada entre threads, permitindo acesso seguro ao cofre compartilhado.

2. Conceito

Shared State é o modelo onde múltiplas threads compartilham dados via referências inteligentes:

  • Mutex<T>: Mutex (mutual exclusion) — só uma thread acessa o dado por vez
  • Arc<T>: Atomic Reference Counted — referência contada thread-safe
  • MutexGuard: Guard devolvido por lock(), libera automaticamente ao sair de escopo
  • RwLock<T>: Permite múltiplos leitores OU um escritor exclusivo
  • Arc::new(Mutex::new(valor)): Padrão canônico para estado compartilhado mutável

3. Requisitos

  • Criar Arc<Mutex<T>> para estado compartilhado entre threads
  • Usar lock() para acessar dados protegidos
  • Usar RwLock para cenários de leitura/escrita
  • Combinar Arc com Mutex e RwLock

4. Design de Dados

graph LR
    A[Thread 1] --> D[Arc]
    B[Thread 2] --> D
    C[Thread 3] --> D
    D --> E[Mutex]
    E --> F[Dado Compartilhado]

5. Diagrama de Fluxo

flowchart TD
    A[Criar Arc Mutex] --> B[Clonar Arc para threads]
    B --> C[Thread: lock]
    C --> D{Mutex livre?}
    D -->|Sim| E[Acessar dado]
    D -->|Não| F[Aguardar]
    F --> D
    E --> G[Modificar dado]
    G --> H[Drop MutexGuard]
    H --> I[Join threads]
    I --> J[Ler resultado final]

6. Funções

Função Descrição
incrementar_com_mutex Incrementa contador usando Arc<Mutex<i32>>
somar_paralelo Soma valores em paralelo com Arc<Mutex<i32>>
coletar_resultados Múltiplas threads adicionam a Arc<Mutex<Vec<i32>>>
contar_palavras Conta palavras usando Arc<Mutex<HashMap>>
atualizar_config Atualiza config compartilhado com Arc<RwLock>
media_paralela Calcula média usando Arc<Mutex> para soma e contagem
buffer_circular Buffer circular thread-safe com Arc<Mutex<Vec>>
estado_do_mecha Gerencia estado compartilhado do mecha com Arc<Mutex>

7. Exemplo

use std::sync::{Arc, Mutex};
use std::thread;

let contador = Arc::new(Mutex::new(0));
let mut handles = vec![];

for _ in 0..10 {
    let contador_clone = Arc::clone(&contador);
    handles.push(thread::spawn(move || {
        let mut num = contador_clone.lock().unwrap();
        *num += 1;
    }));
}

for handle in handles {
    handle.join().unwrap();
}
assert_eq!(*contador.lock().unwrap(), 10);

8. Missão

  1. Implementar incrementar_com_mutex usando Arc<Mutex<i32>> com múltiplas threads
  2. Implementar somar_paralelo dividindo trabalho entre threads
  3. Implementar coletar_resultados com Arc<Mutex<Vec<i32>>>
  4. Implementar contar_palavras usando Arc<Mutex<HashMap<String, usize>>>
  5. Implementar atualizar_config com Arc<RwLock<HashMap>>
  6. Implementar media_paralela computando soma e contagem em paralelo
  7. Implementar buffer_circular com rotação thread-safe
  8. Implementar estado_do_mecha gerenciando estado complexo compartilhado

9. Como Executar

cargo build
cargo test
cargo clippy -- -D warnings
cargo fmt --check

10. Dicas

  • Sempre use Arc para compartilhar Mutex entre threads — Mutex não é Clone
  • lock() retorna Result<MutexGuard, PoisonError> — use unwrap() ou trate erro
  • MutexGuard implementa Deref e DerefMut — acesse o dado diretamente
  • RwLock::read() permite múltiplos leitores simultâneos
  • RwLock::write() é exclusivo — bloqueia leitores e outros escritores
  • Arc::clone incrementa o contador atômico — é barato (copia o ponteiro)