Leer programmeren met Rust · Les

Delen met Arc en Mutex

Wijzig gedeelde status veilig.

Les 3 van 413 stappen

Delen met Arc en Mutex is een gratis Leer programmeren met Rust-les op CoddyKit. Dit is les 3 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Leer programmeren met Rust. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Leer programmeren met Rust bevat in totaal 4 lessen.

De noodzaak van gedeelde toestand

Soms moeten meerdere threads dezelfde gegevens lezen of bijwerken. Het eigenaarschap aan één thread overdragen is dan niet genoeg.

Rust biedt veilig gedeeld eigenaarschap tussen threads met Arc en veilige mutatie met Mutex. Samen maken ze gedeelde, veranderlijke toestand mogelijk.

Arc: atomische referentietelling

Arc staat voor atomisch getelde referenties. Het werkt net als Rc, maar de teller gebruikt atomische bewerkingen, waardoor het veilig is tussen threads.

Een Arc klonen kopieert de gegevens niet. Alleen de teller wordt verhoogd en er wordt een nieuwe verwijzing naar dezelfde waarde teruggegeven.

use std::sync::Arc;

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

Arc delen tussen threads

Om alleen-lezengegevens te delen, kloon je de Arc één keer per thread en verplaats je elke kloon naar de thread. Alle threads verwijzen naar dezelfde geheugentoewijzing.

Omdat Arc Send en Sync is, wordt dit zonder problemen gecompileerd.

use std::sync::Arc;
use std::thread;

fn main() {
    let data = Arc::new(vec![10, 20, 30]);
    let mut handles = vec![];
    for i in 0..3 {
        let d = Arc::clone(&data);
        handles.push(thread::spawn(move || println!("{}", d[i])));
    }
    for h in handles { h.join().unwrap(); }
}

Arc alleen biedt lezen

Met Arc krijg je gedeeld eigenaarschap, maar alleen gedeelde, onveranderlijke toegang tot de ingesloten waarde.

Je kunt gegevens niet rechtstreeks via een Arc wijzigen, omdat meerdere threads die er tegelijk over beschikken met elkaar zouden kunnen botsen. Je hebt interne veranderlijkheid met een vergrendeling nodig.

Mutex: wederzijdse uitsluiting

Een Mutex beschermt gegevens zodat slechts één thread er tegelijk toegang toe heeft. Je roept lock aan om toegang te krijgen.

lock geeft een Result terug; met uitpakken krijg je een bewakingspointer. Andere threads worden geblokkeerd totdat de bewaker wordt verwijderd.

use std::sync::Mutex;

fn main() {
    let m = Mutex::new(0);
    {
        let mut guard = m.lock().unwrap();
        *guard += 5;
    }
    println!("{:?}", m);
}

De bewaker en RAII

De waarde die lock teruggeeft is een MutexGuard. Je krijgt toegang tot de ingesloten gegevens door er met * naar te verwijzen.

Wanneer de bewaker buiten bereik raakt, wordt de vergrendeling automatisch vrijgegeven. Deze RAII-stijl voorkomt dat je vergeet de vergrendeling vrij te geven.

Arc en Mutex combineren

Om veranderlijke toestand tussen threads te delen, plaats je een Mutex in een Arc. De Arc deelt het eigenaarschap; de Mutex beschermt wijzigingen.

Dit patroon, Arc<Mutex<T>>, is in Rust de standaardmanier om gedeelde, veranderlijke toestand te gebruiken.

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

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let c = Arc::clone(&counter);
    *c.lock().unwrap() += 1;
    println!("{}", *counter.lock().unwrap());
}

Een gedeelde teller

Hier verhogen tien threads elk een gedeelde teller. Elke thread kloont de Arc, vergrendelt de Mutex en telt er één bij op.

Omdat de vergrendeling de toegang na elkaar laat plaatsvinden, is het eindtotaal altijd precies tien.

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 || {
            *c.lock().unwrap() += 1;
        }));
    }
    for h in handles { h.join().unwrap(); }
    println!("{}", *counter.lock().unwrap());
}

Houd kritieke secties kort

De code die wordt uitgevoerd terwijl een vergrendeling actief is, vormt de kritieke sectie. Andere threads wachten daar, dus houd deze kort.

Vergrendel, voer de minimale wijziging uit en geef daarna weer vrij. Vermijd zware berekeningen of invoer en uitvoer terwijl je de vergrendeling vasthoudt.

use std::sync::Mutex;

fn main() {
    let m = Mutex::new(Vec::new());
    {
        let mut v = m.lock().unwrap();
        v.push(1);
    } // lock released here
    println!("{:?}", m.lock().unwrap());
}

Deadlocks en vergiftiging

Als een thread dezelfde Mutex twee keer vergrendelt, of als twee threads twee mutexen in tegengestelde volgorde vergrendelen, kan er een deadlock ontstaan en kan het programma voor altijd blijven hangen.

Als een thread in paniek raakt terwijl hij een vergrendeling vasthoudt, raakt de Mutex vergiftigd en geven latere aanroepen van lock een Err terug.

RwLock voor veel lezers

Wanneer er veel meer leesbewerkingen dan schrijfbewerkingen zijn, kan RwLock beter zijn dan Mutex. Het staat meerdere gelijktijdige lezers of één exclusieve schrijver toe.

Gebruik read voor gedeelde toegang en write voor exclusieve toegang.

use std::sync::RwLock;

fn main() {
    let lock = RwLock::new(5);
    {
        let r = lock.read().unwrap();
        println!("read {}", *r);
    }
    *lock.write().unwrap() += 1;
    println!("{}", *lock.read().unwrap());
}

Korte controle

Test je begrip van Arc en Mutex.

Samenvatting

Je hebt geleerd dat Arc het eigenaarschap tussen threads deelt met atomische referentietelling, maar alleen onveranderlijke toegang toestaat.

Een Mutex beschermt wijzigingen en geeft een bewaker uit die bij verwijdering de vergrendeling vrijgeeft. Combineer ze als Arc<Mutex<T>> voor gedeelde, veranderlijke toestand en let op deadlocks en vergiftiging.

Vervolgens ga je threads samenvoegen en hun resultaten verzamelen.

Gratis beginnen

Leer Rust met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
39
Lessen
144

Veelgestelde vragen

Is de les “Delen met Arc en Mutex” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad Leer programmeren met Rust, waaronder “Delen met Arc en Mutex”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Leer programmeren met Rust bevat in totaal 4 lessen.

Wat leer ik in “Delen met Arc en Mutex”?

Wijzig gedeelde status veilig. Je oefent met Leer programmeren met Rust door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Leer programmeren met Rust te beginnen?

Ervaring vooraf is niet nodig. Leer programmeren met Rust op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Delen met Arc en Mutex”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Leer programmeren met Rust?

Ja. Elke les over Leer programmeren met Rust bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Threads starten
  2. Gegevens naar threads verplaatsen
  3. Delen met Arc en Mutex
  4. Threads samenvoegen en resultaten verzamelen
← Terug naar Leer programmeren met Rust