Mit Arc und Mutex teilen
Verändern Sie gemeinsam genutzten Zustand sicher.
Mit Arc und Mutex teilen ist eine kostenlose Learn Rust Coding-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Learn Rust Coding-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Learn Rust Coding-Kurs umfasst insgesamt 4 Lektionen.
Der Bedarf an gemeinsamem Zustand
Manchmal müssen mehrere Threads dieselben Daten lesen oder aktualisieren. Es reicht nicht aus, den Besitz auf einen einzigen Thread zu übertragen.
Rust bietet Ihnen mit Arc sicheren gemeinsamen Besitz über mehrere Threads hinweg und mit Mutex sichere veränderbare Zugriffe. Zusammen ermöglichen sie einen gemeinsamen, veränderbaren Zustand.
Arc: Atomare Referenzzählung
Arc steht für atomar referenzgezählt. Es ähnelt Rc, aber sein Zähler verwendet atomare Operationen und ist daher über mehrere Threads hinweg sicher.
Das Klonen eines Arc kopiert die Daten nicht. Es erhöht lediglich den Zähler und gibt ein weiteres Handle auf denselben Wert zurück.
use std::sync::Arc;
fn main() {
let shared = Arc::new(vec![1, 2, 3]);
let clone = Arc::clone(&shared);
println!("{:?} {:?}", shared, clone);
}Arc zwischen Threads teilen
Um schreibgeschützte Daten zu teilen, klonen Sie den Arc einmal pro Thread und verschieben jeden Klon in den jeweiligen Thread. Alle Threads zeigen auf dieselbe Allokation.
Da Arc sowohl Send als auch Sync implementiert, lässt sich dies problemlos kompilieren.
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 allein ist schreibgeschützt
Arc ermöglicht gemeinsamen Besitz, aber nur gemeinsamen, unveränderlichen Zugriff auf den enthaltenen Wert.
Sie können Daten nicht direkt über einen Arc verändern, da mehrere Threads, die ihn gleichzeitig halten, in einen Wettlauf geraten würden. Sie benötigen innere Veränderbarkeit mit einer Sperre.
Mutex: Gegenseitiger Ausschluss
Ein Mutex schützt Daten, sodass immer nur ein Thread gleichzeitig darauf zugreifen kann. Für den Zugriff rufen Sie lock auf.
lock gibt ein Result zurück; durch das Entpacken erhalten Sie einen Guard in Form eines Smart Pointers. Andere Threads werden blockiert, bis der Guard verworfen wird.
use std::sync::Mutex;
fn main() {
let m = Mutex::new(0);
{
let mut guard = m.lock().unwrap();
*guard += 5;
}
println!("{:?}", m);
}Der Guard und RAII
Der von lock zurückgegebene Wert ist ein MutexGuard. Auf die enthaltenen Daten greifen Sie zu, indem Sie ihn mit * dereferenzieren.
Wenn der Guard seinen Gültigkeitsbereich verlässt, wird die Sperre automatisch freigegeben. Dieser RAII-Ansatz verhindert, dass das Entsperren vergessen wird.
Arc und Mutex kombinieren
Um veränderbaren Zustand zwischen Threads zu teilen, verpacken Sie einen Mutex in einem Arc. Der Arc teilt den Besitz, während der Mutex die Veränderung schützt.
Dieses Muster, Arc<Mutex<T>>, ist der übliche Weg, gemeinsamen veränderbaren Zustand in Rust umzusetzen.
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());
}Ein gemeinsamer Zähler
Hier erhöht jeder von zehn Threads einen gemeinsamen Zähler. Jeder klont den Arc, sperrt den Mutex und addiert eins.
Da die Sperre den Zugriff serialisiert, beträgt das Endergebnis immer genau zehn.
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());
}Halten Sie kritische Abschnitte kurz
Der Code, der ausgeführt wird, während eine Sperre gehalten wird, bildet den kritischen Abschnitt. Andere Threads warten dort, halten Sie ihn daher kurz.
Sperren Sie, führen Sie die minimale Aktualisierung durch und geben Sie die Sperre anschließend frei. Vermeiden Sie umfangreiche Berechnungen oder Ein-/Ausgaben, solange die Sperre gehalten wird.
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 und Vergiftung
Wenn ein Thread denselben Mutex zweimal sperrt oder zwei Threads zwei Mutexes in umgekehrter Reihenfolge sperren, kann ein Deadlock entstehen und das Programm für immer hängen.
Wenn ein Thread während des Haltens einer Sperre in Panik gerät, wird der Mutex als vergiftet markiert, und spätere Aufrufe von lock geben ein Err zurück.
RwLock für viele Leser
Wenn es deutlich mehr Lese- als Schreibzugriffe gibt, kann RwLock besser geeignet sein als Mutex. Er erlaubt entweder viele gleichzeitige Leser oder genau einen exklusiven Schreiber.
Verwenden Sie read für gemeinsamen Zugriff und write für exklusiven Zugriff.
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());
}Kurztest
Testen Sie Ihr Verständnis von Arc und Mutex.
Zusammenfassung
Sie haben gelernt, dass Arc den Besitz mithilfe atomarer Referenzzählung zwischen Threads teilt, aber nur unveränderlichen Zugriff erlaubt.
Ein Mutex schützt Veränderungen und gibt einen Guard aus, der beim Verwerfen freigegeben wird. Kombinieren Sie beide als Arc<Mutex<T>> für gemeinsamen veränderbaren Zustand, und achten Sie dabei auf Deadlocks und Vergiftung.
Als Nächstes verbinden Sie Threads und sammeln ihre Ergebnisse.
Häufig gestellte Fragen
Ist die Lektion „Mit Arc und Mutex teilen“ kostenlos?
Ja — der vollständige Text von „Mit Arc und Mutex teilen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Learn Rust Coding-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Learn Rust Coding-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Mit Arc und Mutex teilen“?
Verändern Sie gemeinsam genutzten Zustand sicher. Du übst Learn Rust Coding mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Learn Rust Coding zu starten?
Keine Vorkenntnisse erforderlich. Learn Rust Coding auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Mit Arc und Mutex teilen“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Learn Rust Coding-Lektion Code schreiben und ausführen?
Ja. Jede Learn Rust Coding-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Threads erzeugen
- Daten in Threads verschieben
- Mit Arc und Mutex teilen
- Threads verbinden und Ergebnisse sammeln