Rust
Arc<T>
Arc<T> ile eşzamanlı paylaşılan sahiplik öğrenirsin.
Arc<T>
Arc<T> (atomically reference counted), Rc'nin thread güvenli sürümüdür. Sayacı atomik işlemlerle günceller; bu yüzden biraz daha yavaştır ama thread'ler arasında paylaşılabilir:
use std::sync::Arc;
use std::thread;
let veri = Arc::new(vec![1, 2, 3]);
let v = Arc::clone(&veri);
let h = thread::spawn(move || v.iter().sum::<i32>());
println!("{}", h.join().unwrap()); // 6
Her thread kendi Arc kopyasını move ile alır. Veri yalnızca okunur; değiştirmek için Arc<Mutex<T>> gerekir.
Sonuçları sırayla toplamak
Thread'lerin çıktı sırası belirsizdir. Sonuçları join ile almak, hem bitmelerini beklemeyi hem de sıralı toplamayı sağlar:
let tutucular: Vec<_> = (1..=3)
.map(|k| {
let v = Arc::clone(&veri);
thread::spawn(move || v.iter().sum::<i32>() * k)
})
.collect();
let sonuc: Vec<i32> = tutucular.into_iter().map(|h| h.join().unwrap()).collect();
Tüm thread'ler bitince kopyaları da bırakılır ve sayaç yeniden 1 olur.
Uygulama Paralel toplam
Arc::new(vec![1, 2, 3]) paylaş. k = 1..=3 için her biri toplam * k hesaplayan üç thread başlat, sonuçları join ile sırayla topla. Sonuç vektörünü ve son Arc::strong_count değerini boşlukla yazdır.
Örnek çözümü göster
use std::sync::Arc;
use std::thread;
fn main() {
let veri = Arc::new(vec![1, 2, 3]);
let tutucular: Vec<_> = (1..=3)
.map(|k| {
let v = Arc::clone(&veri);
thread::spawn(move || v.iter().sum::<i32>() * k)
})
.collect();
let sonuc: Vec<i32> = tutucular.into_iter().map(|h| h.join().unwrap()).collect();
println!("{:?} {}", sonuc, Arc::strong_count(&veri));
}
Kendini test et
-
<code>thread::spawn(move || ..)</code> içinde <code>Rc</code> kullanılırsa ne olur?
- Çalışır ama yavaştır
- Çalışma anında panic
- Sorun olmaz
- Derleme hatası: Rc thread'ler arasında güvenle gönderilemez (Send değil)
Cevabı göster
Derleme hatası: Rc thread'ler arasında güvenle gönderilemez (Send değil) — Derleyici Send/Sync trait'leriyle veri yarışlarını derleme anında engeller.
-
Thread güvenli paylaşım
use std::sync::Arc;
let veri = ____::new(vec![1, 2, 3]);
Cevabı göster
use std::sync::Arc;
let veri = Arc::new(vec![1, 2, 3]);
-
Tür ve özelliği
- Rc<T>
- Tek thread, paylaşım
- Arc<T>
- Çok thread, paylaşım
- Box<T>
- Tek sahip
- Arc<Mutex<T>>
- Paylaşımlı değiştirme
Sıradaki ders: Box ve recursion