CodeBlanks Logo Icon CodeBlanks

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.

Başlangıç kodu

main.rs
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
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);
}

Beklenen çıktı

["ali", "ece"]

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Kilit altındayken bir istemciye ağ üzerinden yazmak neden kötü bir fikirdir?

  • Yavaş bir istemci kilidi uzun tutar ve tüm odayı dondurur Doğru cevap
  • Yazma başarısız olur
  • Derlenmez
  • Kötü değildir

Açıklama: Kilit altında yalnızca listenin kopyasını al; G/Ç'yi kilit bırakıldıktan sonra yap.

2 Ayrılanı çıkar

Soru
fn ayril(&mut self, ad: &str) {
    self.uyeler.____(|k| k != ad);
}
Cevap
fn ayril(&mut self, ad: &str) {
    self.uyeler.retain(|k| k != ad);
}

Açıklama: retain koşulu sağlamayanları siler.

3 İşlem ve oda durumu

Kavram Anlamı
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

İleri seviye bölümündeki tüm dersler