You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
use std::sync::Arc;fnmain(){let data = Arc::new(vec![1,2,3]);let data_clone = Arc::clone(&data);
std::thread::spawn(move || {println!("{:?}", data_clone);// ✅ OK});println!("{:?}", data);// ✅ OK aussi}
Arc + Mutex : lecture ET écriture partagée
use std::sync::{Arc,Mutex};#[derive(Default)]pubstructSharedState{pubcounter:i32,pubmessages:Vec<String>,}pubstructApp{state:Arc<Mutex<SharedState>>,}implApp{pubfnnew() -> Self{Self{state:Arc::new(Mutex::new(SharedState::default())),}}pubfnincrement(&self){letmut state = self.state.lock().unwrap();
state.counter += 1;}pubfnspawn_worker(&self){let state = Arc::clone(&self.state);
std::thread::spawn(move || {// Le worker peut modifier l'étatletmut state = state.lock().unwrap();
state.messages.push("Message from worker".to_string());});}}
ArcSwap : échange atomique sans lock
Le problème de Mutex
// ❌ Mutex bloque même pour la lecturelet state = Arc<Mutex<AppState>>;let state = state.lock().unwrap();// Bloque si quelqu'un écritlet value = state.some_field;// Lecture simple mais bloquée
Solution : ArcSwap
# Cargo.toml
[dependencies]
arc-swap = "1.7"
use arc_swap::ArcSwap;use std::sync::Arc;pubstructAppState{pubusers:Vec<User>,pubsettings:Settings,}pubstructApp{// État partagé, lecture sans lockstate:Arc<ArcSwap<AppState>>,}implApp{pubfnnew() -> Self{Self{state:Arc::new(ArcSwap::from_pointee(AppState{users:vec![],settings:Settings::default(),})),}}/// Lecture sans lock (très rapide)pubfnget_users(&self) -> Vec<User>{let state = self.state.load();
state.users.clone()// Clone de la référence Arc}/// Mise à jour atomiquepubfnupdate_state(&self,new_state:AppState){self.state.store(Arc::new(new_state));}/// Mise à jour avec transformationpubfnadd_user(&self,user:User){self.state.rcu(|state| {letmut new_state = (**state).clone();
new_state.users.push(user);Arc::new(new_state)});}}
Pattern : Store global avec ArcSwap
use arc_swap::ArcSwap;use std::sync::Arc;pubstructGlobalStore{state:Arc<ArcSwap<AppState>>,}implGlobalStore{pubfnnew() -> Self{Self{state:Arc::new(ArcSwap::from_pointee(AppState::default())),}}/// Lecture rapide depuis n'importe quel threadpubfnread(&self) -> Arc<AppState>{self.state.load_full()}/// Écriture atomiquepubfnwrite(&self,new_state:AppState){self.state.store(Arc::new(new_state));}/// Mise à jour fonctionnellepubfnupdate<F>(&self,f:F)whereF:FnOnce(&AppState) -> AppState,{self.state.rcu(|state| Arc::new(f(state)));}}
Comparaison des approches
Approche
Lecture
Écriture
Performance
Arc<Mutex<T>>
Lock requis
Lock requis
Plus lent
Arc<ArcSwap<T>>
Pas de lock
Atomic swap
Plus rapide
Arc<RwLock<T>>
Lock partagé
Lock exclusif
Moyen
Résumé
Arc : Partage de données entre threads
ArcSwap : Échange atomique sans lock pour lecture
RCU (Read-Copy-Update) : Pattern pour mises à jour fonctionnelles
Idéal pour : État global lu fréquemment, écrit occasionnellement