Rust
Arc<Mutex> durumu
Paylaşılan durumu Arc<Mutex<>> ile yönetirsin.
Arc<Mutex> durumu
Sohbet odasının kim bağlı listesi, tüm istemci thread'lerinin okuyup değiştirdiği ortak bir durumdur. Arc<Mutex<Oda>> ile paylaşılır; her değişiklik kısa bir kilit altında yapılır:
struct Oda {
uyeler: Vec<String>,
}
impl Oda {
fn katil(&mut self, ad: &str) { self.uyeler.push(ad.to_string()); }
fn ayril(&mut self, ad: &str) { self.uyeler.retain(|k| k != ad); }
}
let oda = Arc::new(Mutex::new(Oda { uyeler: Vec::new() }));
Metotları Oda üzerinde tutmak, kilitleme kodunu iş mantığından ayırır: oda.lock().unwrap().katil("ece").
Thread'lerden katılım
Her istemci thread'i odaya kendi adını ekler. Thread'lerin bitiş sırası belirsiz olduğu için liste yazdırılmadan önce sıralanır:
let tutucular: Vec<_> = ["ece", "can", "ali"]
.into_iter()
.map(|ad| {
let oda = Arc::clone(&oda);
thread::spawn(move || oda.lock().unwrap().katil(ad))
})
.collect();
for t in tutucular { t.join().unwrap(); }
oda.lock().unwrap().ayril("can");
Uygulama Oda durumu
Yukarıdaki Oda türünü yaz ve Arc<Mutex<Oda>> ile paylaş. ece, can, ali ayrı thread'lerden katılsın; hepsi bitince can ayrılsın. Kullanıcı listesini sıralayıp {:?} ile yazdır.
Örnek çözümü göster
use std::sync::{Arc, Mutex};
use std::thread;
struct Oda {
uyeler: Vec<String>,
}
impl Oda {
fn katil(&mut self, ad: &str) {
self.uyeler.push(ad.to_string());
}
fn ayril(&mut self, ad: &str) {
self.uyeler.retain(|k| k != ad);
}
}
fn main() {
let oda = Arc::new(Mutex::new(Oda { uyeler: Vec::new() }));
let tutucular: Vec<_> = ["ece", "can", "ali"]
.into_iter()
.map(|ad| {
let oda = Arc::clone(&oda);
thread::spawn(move || oda.lock().unwrap().katil(ad))
})
.collect();
for t in tutucular {
t.join().unwrap();
}
oda.lock().unwrap().ayril("can");
let mut liste = oda.lock().unwrap().uyeler.clone();
liste.sort();
println!("{:?}", liste);
}
Kendini test et
-
Kilit altındayken bir istemciye ağ üzerinden yazmak neden kötü bir fikirdir?
- Yavaş bir istemci kilidi uzun tutar ve tüm odayı dondurur
- Yazma başarısız olur
- Derlenmez
- Kötü değildir
Cevabı göster
Yavaş bir istemci kilidi uzun tutar ve tüm odayı dondurur — Kilit altında yalnızca listenin kopyasını al; G/Ç'yi kilit bırakıldıktan sonra yap.
-
Ayrılanı çıkar
fn ayril(&mut self, ad: &str) {
self.uyeler.____(|k| k != ad);
}
Cevabı göster
fn ayril(&mut self, ad: &str) {
self.uyeler.retain(|k| k != ad);
}
-
İşlem ve oda durumu
- ece, can, ali katıldı
- 3 kullanıcı
- can ayrıldı
- 2 kullanıcı
- Sıralı liste
- ["ali", "ece"]
- lock() kısa tutulur
- Oda donmaz
Sıradaki ders: unsafe bloğu