0Pricing
Learn Rust Coding · Ders

Durumu Arc/Mutex ile Paylaşma

Güvenli paylaşılan veriler

Durumu Arc/Mutex ile Paylaşma, CoddyKit'te ücretsiz bir Learn Rust Coding dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Learn Rust Coding öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Learn Rust Coding kursu toplamda 4 dersten oluşur.

Paylaşılan Durum Neden Zordur?

Bazen ileti aktarımı yeterli olmaz ve birden çok iş parçacığının gerçekten aynı veriyi okuyup yazması gerekir. Rust, koruma olmadan değiştirilebilir bir değeri iş parçacıkları arasında paylaşmanıza izin vermez; çünkü bu bir veri yarışına yol açabilir.

Birlikte kullandığınız iki araç şunlardır:

  • İş parçacıkları arasında paylaşılan sahiplik için Arc.
  • Güvenli ve ayrıcalıklı değişiklik için Mutex.

Rc İş Parçacığı Güvenli Değildir

Rc, paylaşılan sahiplik sağlar ancak yalnızca tek bir iş parçacığında kullanılabilir. Başvuru sayacı eşzamanlı olmadığından derleyici onu iş parçacıkları arasında göndermenizi reddeder. Çok iş parçacıklı paylaşım için Arc (Atomik Başvuru Sayımlı) gerekir.

Arc, Rc gibi davranır ancak sayacını atomik işlemlerle günceller; böylece kopyaları iş parçacıkları arasında güvenle kullanılabilir.

use std::sync::Arc;

fn main() {
    let data = Arc::new(vec![1, 2, 3]);
    let clone1 = Arc::clone(&data);
    println!("original: {:?}", data);
    println!("clone:    {:?}", clone1);
    println!("count:    {}", Arc::strong_count(&data));
}

Mutex Ayrıcalıklı Erişim Sağlar

Bir Mutex, verileri sarar ve aynı anda yalnızca bir iş parçacığının erişmesini garanti eder. İç değere başvuru yapan bir MutexGuard almak için .lock() çağrısını yaparsınız. Koruyucu kapsam dışına çıktığında kilit otomatik olarak serbest bırakılır.

use std::sync::Mutex;

fn main() {
    let m = Mutex::new(5);
    {
        let mut num = m.lock().unwrap();
        *num += 10;
    } // guard dropped here, lock released
    println!("value = {:?}", m.lock().unwrap());
}

Arc ve Mutex'i Birleştirme

Değiştirilebilir verileri iş parçacıkları arasında paylaşmak için onları Arc> olarak sarın:

  • Arc, birçok iş parçacığının aynı verilere ait bir tutamağa sahip olmasını sağlar.
  • Mutex, her iş parçacığının veriyi güvenle ve sırayla değiştirmesini sağlar.

Oluşturmadan önce her iş parçacığı için Arc'ı clone edin.

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let c = Arc::clone(&counter);
    let handle = thread::spawn(move || {
        let mut n = c.lock().unwrap();
        *n += 1;
    });
    handle.join().unwrap();
    println!("counter = {}", *counter.lock().unwrap());
}

Birçok İş Parçacığı Arasında Paylaşılan Sayaç

Klasik örnek şudur: on iş parçacığının her biri paylaşılan bir sayacı artırır. Her iş parçacığı kendi Arc kopyasını tutar ve bir eklemek için Mutex'i kilitler. Tüm iş parçacıkları birleştirildikten sonra, veri yarışı olmadan toplam tam olarak 10 olur.

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];
    for _ in 0..10 {
        let c = Arc::clone(&counter);
        handles.push(thread::spawn(move || {
            let mut num = c.lock().unwrap();
            *num += 1;
        }));
    }
    for h in handles {
        h.join().unwrap();
    }
    println!("Result: {}", *counter.lock().unwrap());
}

Kilit Kapsamı Önemlidir

MutexGuard, bırakılana kadar kilidi elinde tutar. Onu yavaş işlemler sırasında tutmak diğer iş parçacıklarını engeller. Kritik bölümleri kısa tutun: kilitleyin, değiştirin, serbest bırakın. Kilidi küçük bir blok içine almak, ek işlemlerden önce kilidin bırakılmasını sağlar.

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let log = Arc::new(Mutex::new(Vec::new()));
    let mut handles = vec![];
    for i in 0..3 {
        let l = Arc::clone(&log);
        handles.push(thread::spawn(move || {
            {
                let mut v = l.lock().unwrap();
                v.push(i);
            } // released quickly
        }));
    }
    for h in handles { h.join().unwrap(); }
    let mut result = log.lock().unwrap().clone();
    result.sort();
    println!("{:?}", result);
}

Kilitlenme: Gerçek Bir Risk

Kilitlenme, iki iş parçacığının birbirinin ihtiyaç duyduğu bir kilidi elinde tutması ve ikisinin de sonsuza kadar beklemesi durumunda oluşur. Rust veri yarışlarını önler, ancak kilitlenmeleri önlemez. Birden çok mutex'i her zaman aynı sırayla kilitleyerek ve kilitleri kısa süre tutarak bunlardan kaçının.

Ayrıca aynı iş parçacığında aynı Mutex'i iki kez kilitlemekten kaçının; standart Mutex yeniden girişli değildir.

Bir İş Parçacığı Paniklediğinde Zehirlenme

Bir iş parçacığı kilidi elinde tutarken paniklerse Mutex zehirlenmiş olur. Daha sonraki .lock() çağrıları, verilerin tutarsız olabileceğini belirtmek için Err döndürür. Verilerin hâlâ kullanılabilir olduğuna karar verirseniz hata üzerindeki into_inner() ile iç koruyucuyu kurtarabilirsiniz.

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let data = Arc::new(Mutex::new(0));
    let d = Arc::clone(&data);
    let _ = thread::spawn(move || {
        let mut g = d.lock().unwrap();
        *g = 7;
        panic!("boom"); // poisons the mutex
    }).join();
    match data.lock() {
        Ok(g) => println!("ok: {}", *g),
        Err(poisoned) => println!("recovered: {}", *poisoned.into_inner()),
    }
}

Çok Sayıda Okuyucu için RwLock

Okumalar yazmalardan çok daha fazlaysa RwLock, Mutex'ten daha hızlı olabilir. Birçok eşzamanlı okuyucuya veya tek bir yazıcıya izin verir. Paylaşılan erişim için .read(), ayrıcalıklı erişim için .write() kullanın.

use std::sync::{Arc, RwLock};
use std::thread;

fn main() {
    let config = Arc::new(RwLock::new(String::from("v1")));
    let reader = Arc::clone(&config);
    let r = thread::spawn(move || {
        let val = reader.read().unwrap();
        println!("read: {}", *val);
    });
    r.join().unwrap();
    {
        let mut w = config.write().unwrap();
        *w = String::from("v2");
    }
    println!("final: {}", *config.read().unwrap());
}

Basit Sayaçlar için Atomikler

Tek bir tamsayı sayacı için tam bir Mutex kullanmak gereğinden fazladır. AtomicUsize gibi türler, fetch_add gibi yöntemlerle kilitsiz güncellemeler sunar. Bunları iş parçacıkları arasında paylaşmak için Arc ile sarın. Bir Ordering seçin; SeqCst en basit güvenli varsayılandır.

use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;

fn main() {
    let counter = Arc::new(AtomicUsize::new(0));
    let mut handles = vec![];
    for _ in 0..5 {
        let c = Arc::clone(&counter);
        handles.push(thread::spawn(move || {
            c.fetch_add(1, Ordering::SeqCst);
        }));
    }
    for h in handles { h.join().unwrap(); }
    println!("count = {}", counter.load(Ordering::SeqCst));
}

Doğru Aracı Seçme

Paylaşılan durum için hızlı bir rehber:

  • Channel: sahipliği aktarır, işlem hattı tarzındadır.
  • Arc<Mutex>: okuma ve yazmanın karışık olduğu, değiştirilebilir paylaşılan yapılar içindir.
  • Arc<RwLock>: yoğun okunan paylaşılan veriler içindir.
  • Atomics: tekil ilkel sayaçlar veya bayraklar içindir.

İhtiyacınızı karşılayan en basit aracı tercih edin; kilitlere yalnızca ileti aktarımı problemi iyi modellemediğinde başvurun.

Hızlı Kontrol

Paylaşılan durumu ne kadar anladığınızı test edin.

Özet

Durumu iş parçacıkları arasında güvenle paylaşmayı öğrendiniz:

  • Arc, iş parçacığı güvenli paylaşılan sahiplik sağlar; Rc sağlamaz.
  • Mutex, otomatik olarak kilidi açılan bir koruyucu aracılığıyla ayrıcalıklı değişiklik sağlar.
  • Arc<Mutex<T>>, değiştirilebilir paylaşılan veriler için standart desendir.
  • Kilit kapsamlarını kısa tutun; kilitlenmelere ve zehirlenmeye dikkat edin.
  • RwLock yoğun okunan veriler için, atomikler ise basit sayaçlar için uygundur.

Sıkça Sorulan Sorular

“Durumu Arc/Mutex ile Paylaşma” dersi ücretsiz mi?

Evet — “Durumu Arc/Mutex ile Paylaşma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Learn Rust Coding kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Learn Rust Coding kursu toplamda 4 dersten oluşur.

“Durumu Arc/Mutex ile Paylaşma” dersinde ne öğreneceğim?

Güvenli paylaşılan veriler Learn Rust Coding ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Learn Rust Coding öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Learn Rust Coding, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.

“Durumu Arc/Mutex ile Paylaşma” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Learn Rust Coding dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Learn Rust Coding dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. mpsc Kanalları
  2. Durumu Arc/Mutex ile Paylaşma
  3. Kapsamlı İş Parçacıkları
  4. Crossbeam Kanalları
← Learn Rust Coding Sayfasına Dön