Rust
Mutex<T>
Mutex<T> ile karşılıklı dışlama (mutual exclusion) yaparsın.
Mutex<T>
Mutex<T> (karşılıklı dışlama), veriye aynı anda yalnızca bir thread'in erişmesini sağlar. lock() bir guard döndürür; guard yaşadığı sürece kilit tutulur ve guard bırakılınca kilit kendiliğinden açılır:
use std::sync::{Arc, Mutex};
let sayac = Arc::new(Mutex::new(0));
let mut h = Vec::new();
for _ in 0..8 {
let s = Arc::clone(&sayac);
h.push(thread::spawn(move || {
for _ in 0..100 {
*s.lock().unwrap() += 1;
}
}));
}
Rust'ta veri mutex'in içinde durur; kilidi almadan veriye ulaşmanın yolu yoktur. Bu, "kilidi almayı unuttum" hatasını imkânsız kılar.
Kilit süresi ve deadlock
Guard'ı uzun tutmak diğer thread'leri bekletir. İki kilit farklı sırayla alınırsa iki thread birbirini sonsuza dek bekleyebilir (deadlock). Kurallar: kilidi kısa tut, kilit altında yavaş iş yapma, birden çok kilidi hep aynı sırayla al:
{
let mut veri = kilitli.lock().unwrap();
veri.push(1);
} // guard burada bırakılır, kilit açılır
yavas_islem(); // kilit tutulmadan
Rust veri yarışlarını önler, ama deadlock mantıksal bir hatadır ve derleyici onu yakalamaz.
Uygulama Paylaşılan sayaç
Arc<Mutex<i32>> sayacı 8 thread ile paylaş; her thread sayacı 100 kez artırsın. Tüm thread'leri join ettikten sonra son değeri yazdır.
Örnek çözümü göster
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let sayac = Arc::new(Mutex::new(0));
let mut h = Vec::new();
for _ in 0..8 {
let s = Arc::clone(&sayac);
h.push(thread::spawn(move || {
for _ in 0..100 {
*s.lock().unwrap() += 1;
}
}));
}
for t in h {
t.join().unwrap();
}
println!("{}", *sayac.lock().unwrap());
}
Kendini test et
-
<code>lock()</code> neden <code>Result</code> döndürür?
- Zaman aşımı için
- Gelenek
- Kilidi tutan bir thread panic verdiyse mutex "zehirlenir" (poisoned)
- Kilit alınamayabilir
Cevabı göster
Kilidi tutan bir thread panic verdiyse mutex "zehirlenir" (poisoned) — Zehirlenme, verinin yarım kalmış bir güncelleme yüzünden tutarsız olabileceği uyarısıdır.
-
Kilidi al
*s.____().unwrap() += 1;
Cevabı göster
*s.lock().unwrap() += 1;
-
Kavram ve anlamı
- Mutex::lock()
- MutexGuard
- guard drop
- Kilit açılır
- poisoned
- Kilit sahibi panic verdi
- deadlock
- Karşılıklı bekleme
Sıradaki ders: RwLock<T>