Threads verbinden und Ergebnisse sammeln
Warten Sie auf Threads und sammeln Sie deren Ausgabe.
Threads verbinden und Ergebnisse sammeln ist eine kostenlose Learn Rust Coding-Lektion auf CoddyKit. Dies ist Lektion 4 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.
Warum Threads verbinden?
Das Starten eines Threads setzt die Arbeit in Gang, aber meistens benötigen Sie das Ergebnis oder zumindest den Nachweis, dass die Arbeit abgeschlossen wurde. Durch das Verbinden warten Sie darauf.
In dieser Lektion sammeln Sie Handles, verbinden die Threads und fassen die von ihnen erzeugten Werte zu einem Endergebnis zusammen.
join gibt ein Result zurück
join gibt ein Result zurück. Bei Erfolg enthält es den Rückgabewert der Closure; bei einer Thread-Panik enthält es ein Err.
Der Aufruf von unwrap gibt den Wert direkt zurück, löst aber eine Panik aus, wenn der Thread fehlgeschlagen ist.
use std::thread;
fn main() {
let h = thread::spawn(|| 7 * 6);
let value: i32 = h.join().unwrap();
println!("answer = {}", value);
}Zuerst die Handles sammeln
Um Threads parallel auszuführen, starten Sie sie alle, bevor Sie einen von ihnen verbinden. Fügen Sie jedes Handle währenddessen in einen Vektor ein.
Wenn Sie innerhalb der Startschleife einen Thread verbinden, wird jeder Thread beendet, bevor der nächste startet, und Sie verlieren die Parallelität.
use std::thread;
fn main() {
let handles: Vec<_> = (0..4)
.map(|i| thread::spawn(move || i * i))
.collect();
for h in handles {
println!("{}", h.join().unwrap());
}
}Ergebnisse in einem Vec sammeln
Sie können jedes Handle verbinden und die zurückgegebenen Werte in einen Ergebnisvektor einfügen.
Startreihenfolge und Verbindungsreihenfolge laufen hier beide von null bis drei, daher erhält der Ergebnisvektor eine vorhersehbare Reihenfolge.
use std::thread;
fn main() {
let handles: Vec<_> = (1..=4)
.map(|n| thread::spawn(move || n * 10))
.collect();
let results: Vec<i32> = handles
.into_iter()
.map(|h| h.join().unwrap())
.collect();
println!("{:?}", results);
}Parallele Ergebnisse summieren
Sobald Sie Ergebnisse gesammelt haben, können Sie sie reduzieren. Hier berechnet jeder Thread einen Teilwert, und main addiert sie.
Diese Struktur aus Map und Reduce ist ein verbreitetes paralleles Muster.
use std::thread;
fn main() {
let handles: Vec<_> = (1..=5)
.map(|n| thread::spawn(move || n * n))
.collect();
let total: i32 = handles
.into_iter()
.map(|h| h.join().unwrap())
.sum();
println!("total = {}", total);
}Arbeit in Blöcke aufteilen
Bei größeren Datenmengen teilen Sie die Daten in Blöcke auf und übergeben jeden Block an einen eigenen Thread. Jeder Thread gibt eine Teilsumme zurück.
Wenn Sie jeden Block in einen eigenen Vec klonen, kann der Thread seinen Teil sicher besitzen.
use std::thread;
fn main() {
let data: Vec<i32> = (1..=10).collect();
let handles: Vec<_> = data
.chunks(5)
.map(|c| { let c = c.to_vec(); thread::spawn(move || c.iter().sum::<i32>()) })
.collect();
let total: i32 = handles.into_iter().map(|h| h.join().unwrap()).sum();
println!("{}", total);
}Eine Thread-Panik behandeln
Wenn ein Worker in Panik geraten könnte, verwenden Sie nicht blind unwrap. Werten Sie das Result von join mit match aus, um den Fehlerpfad zu behandeln.
So bleibt der Hauptthread aktiv, auch wenn ein Worker fehlschlägt.
use std::thread;
fn main() {
let h = thread::spawn(|| {
if true { panic!("failed"); }
1
});
match h.join() {
Ok(v) => println!("got {}", v),
Err(_) => println!("thread panicked"),
}
}In einen gemeinsamen Vec sammeln
Statt Werte zurückzugeben, können Threads in einen gemeinsamen Arc<Mutex<Vec>> einfügen. Die Reihenfolge ist dann nichtdeterministisch.
Nachdem Sie alle Threads verbunden haben, sperren Sie den Vektor einmal, um alle gesammelten Ergebnisse zu lesen.
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let out = Arc::new(Mutex::new(vec![]));
let mut handles = vec![];
for i in 0..3 {
let o = Arc::clone(&out);
handles.push(thread::spawn(move || o.lock().unwrap().push(i)));
}
for h in handles { h.join().unwrap(); }
println!("{:?}", out.lock().unwrap());
}Threads mit begrenztem Gültigkeitsbereich
thread::scope ermöglicht es Threads, lokale Daten ohne move oder Arc zu leihen. Der Gültigkeitsbereich garantiert, dass alle Threads beendet sind, bevor er zurückkehrt.
Dadurch werden parallele Lesezugriffe auf Stack-Daten ergonomisch und sicher.
use std::thread;
fn main() {
let data = vec![1, 2, 3];
thread::scope(|s| {
s.spawn(|| println!("sum {}", data.iter().sum::<i32>()));
s.spawn(|| println!("len {}", data.len()));
});
}Ergebnisse aus einem Scope zurückgeben
Threads innerhalb eines Scopes können über ihre Handles ebenfalls Werte zurückgeben. Verbinden Sie sie innerhalb des Scopes, um die Ergebnisse zu sammeln.
Da der Scope bis zum Abschluss blockiert, bleiben geliehene Daten während der gesamten Zeit gültig.
use std::thread;
fn main() {
let nums = vec![4, 5, 6];
let total = thread::scope(|s| {
let h = s.spawn(|| nums.iter().sum::<i32>());
h.join().unwrap()
});
println!("total = {}", total);
}Vergessen Sie nicht, Threads zu verbinden
Wenn Sie ein JoinHandle verwerfen, ohne den Thread zu verbinden, wird der Thread abgekoppelt. Er läuft weiter, aber Sie verlieren sein Ergebnis und jede Möglichkeit, auf ihn zu warten.
Der Prozess kann außerdem beendet werden, bevor ein abgekoppelter Thread fertig ist. Verbinden Sie den Thread, wenn Sie das Ergebnis oder den Abschluss benötigen.
Kurztest
Testen Sie Ihr Verständnis des Verbindens von Threads und des Sammelns von Ergebnissen.
Zusammenfassung
Sie haben gelernt, dass join ein Result zurückgibt, das entweder den Wert eines Threads oder dessen Panik enthält. Starten Sie zuerst alle Threads und verbinden Sie sie anschließend, damit die Parallelität erhalten bleibt.
Sie können Ergebnisse in einem Vec sammeln, sie reduzieren oder in einen gemeinsamen Arc<Mutex<Vec>> einfügen. Threads mit begrenztem Gültigkeitsbereich leihen lokale Daten sicher, und das Verwerfen eines Handles koppelt den Thread ab.
Damit verfügen Sie über die grundlegenden Werkzeuge für Threads und gemeinsamen Zustand in Rust.
Lerne Rust mit einem KI-Tutor — kostenlos
Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.
- Kurse
- 39
- Lektionen
- 144
Häufig gestellte Fragen
Ist die Lektion „Threads verbinden und Ergebnisse sammeln“ kostenlos?
Ja — der vollständige Text von „Threads verbinden und Ergebnisse sammeln“ 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 „Threads verbinden und Ergebnisse sammeln“?
Warten Sie auf Threads und sammeln Sie deren Ausgabe. 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 4 von 4.
Wie lange dauert die Lektion „Threads verbinden und Ergebnisse sammeln“?
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