Tarihsel olarak, çoklu iş parçacığı ile çalışma çökme, yarış durumu ve bellek sızıntıları ile tehlikelerle doluydu, özellikle kontrolsüz bellek paylaşımı durumunda. Rust, tür seviyesinde iş parçacığı güvenliği kavramını uygular — bir nesne, yalnızca gerekli trait'leri (Send, Sync) uyguluyorsa bir iş parçacığına geçirilebilir. İş parçacıkları, std::thread::spawn aracılığıyla oluşturulur ve aralarındaki iletişim, kanallar veya kontrollü değişim ile paylaşılan bellek (Mutex, Arc) yoluyla gerçekleştirilir.
Sorun: Senkronizasyonu manuel olarak yönetmek zor ve tehlikelidir. İş parçacıkları arasında rastgele nesnelerin açık bir sahiplik devri olmadan iletilmesi, yarış durumlarına ve çöküşlere yol açar.
Çözüm: yalnızca açıkça taşınabilir (move) nesneler veya Arc, Mutex üzerinden paylaşılan nesneler ile birlikte yerleşik mesaj kanalları (std::sync::mpsc, crossbeam) kullanılır. Bu, senkron ve asenkron veri alışverişi ile ilgili hataları en az seviyeye indirir: sahiplik her zaman nettir.
Kod örneği:
use std::thread; use std::sync::mpsc; fn main() { let (tx, rx) = mpsc::channel(); thread::spawn(move || { tx.send(String::from("Thread'den merhaba!")).unwrap(); }); let received = rx.recv().unwrap(); println!("Alınan: {}", received); }
Ana özellikler:
Bir nesne move ile geçirildikten sonra ana iş parçacığında kullanılmaya devam edebilir mi?
Hayır, nesne bir kere taşındığı zaman (örneğin, thread::spawn içindeki closure'a), onu ana iş parçacığında kullanmak mümkün değildir, derleyici kodu derlemenize izin vermez.
Mütat referansları (&mut T) arasında iletim yapılabilir mi?
Hayır, mütabit referans &mut T yalnızca tek bir örnekte var olabilir ve trait Send varsayılan olarak ona uygulanmamıştır. Değişken verilerle çalışmak için Mutex/Arc üzerinden bir sarma kullanılır.
Neden Rc<T> iş parçacıkları arasında sahipliği paylaşmak için kullanılamaz?
Rc<T> senkronize ve güvenli değildir çünkü iç sayacı iş parçacığı güvenli değildir. Thread-safe için Arc<T> (atomik referans sayacı) kullanılır.
// Rc ve Arc karşılaştırması use std::sync::Arc; let x = Arc::new(5); // kopyalanabilir ve iş parçacıkları arasında paylaşılabilir
Bir geliştirici, iş parçacıkları arasında bir dize paylaşmak için Rc<String> kullanmaya karar verir, Rc'yi thread::spawn içine koyar. Kod yalnızca unsafe aracılığıyla zorla tür değiştirilirse derlenir, ardından uygulama çökebilir veya bozulmuş verilerle çalışabilir.
Artıları:
Eksileri:
Güvenli erişim için Arc<String> + Mutex<String> kullanılır veya mesaj iletimi kanaldan yapılır, ortak sahiplik olmadan.
Artıları:
Eksileri: