0Pricing
Learn Rust Coding · Leçon

Rejoindre les threads et recueillir les résultats

Attendez les threads et rassemblez la sortie.

Rejoindre les threads et recueillir les résultats est une leçon Learn Rust Coding gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Learn Rust Coding, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Learn Rust Coding comprend 4 leçons au total.

Pourquoi joindre les threads ?

La création démarre le travail, mais vous avez généralement besoin de son résultat ou au moins de la preuve qu’il est terminé. La jointure permet d’attendre.

Dans cette leçon, vous allez collecter des handles, les joindre et rassembler les valeurs qu’ils produisent dans une réponse finale.

join renvoie un Result

join renvoie un Result. En cas de réussite, il contient la valeur renvoyée par la fermeture ; en cas de panique d’un thread, il contient un Err.

Appeler unwrap fournit directement la valeur, mais propage une panique si le thread a échoué.

use std::thread;

fn main() {
    let h = thread::spawn(|| 7 * 6);
    let value: i32 = h.join().unwrap();
    println!("answer = {}", value);
}

Collecter d’abord les handles

Pour exécuter des fils d’exécution en parallèle, lancez-les tous avant d’attendre le résultat de l’un d’eux. Ajoutez chaque poignée à un vecteur au fur et à mesure.

Si vous attendez le résultat dans la boucle de lancement, chaque fil se termine avant que le suivant ne démarre, ce qui supprime le parallélisme.

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());
    }
}

Rassembler les résultats dans un vecteur

Vous pouvez attendre le résultat de chaque poignée et ajouter les valeurs renvoyées à un vecteur de résultats.

L’ordre de lancement et l’ordre d’attente vont tous deux de zéro à trois ici, le vecteur de résultats conserve donc un ordre prévisible.

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);
}

Additionner les résultats parallèles

Une fois les résultats rassemblés, vous pouvez les réduire. Ici, chaque fil calcule une valeur partielle, puis main les additionne.

Cette structure « map puis reduce » est un schéma parallèle courant.

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);
}

Répartir le travail en blocs

Pour traiter des données plus volumineuses, divisez-les en blocs et attribuez chaque bloc à son propre fil. Chaque fil renvoie une somme partielle.

Cloner chaque bloc dans un Vec possédé permet au fil de posséder sa portion en toute sécurité.

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);
}

Gérer la panique d’un fil

Si un fil de travail risque de paniquer, n’utilisez pas unwrap aveuglément. Faites un filtrage sur le Result renvoyé par join pour gérer le chemin d’erreur.

Le fil principal reste ainsi actif même lorsqu’un fil de travail échoue.

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"),
    }
}

Rassembler les résultats dans un vecteur partagé

Au lieu de renvoyer des valeurs, les fils peuvent les ajouter à un Arc<Mutex<Vec>> partagé. L’ordre devient alors non déterministe.

Après avoir attendu la fin de tous les fils, verrouillez le vecteur une seule fois pour lire chaque résultat rassemblé.

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());
}

Fils d’exécution délimités

thread::scope permet aux fils d’emprunter des données locales sans move ni Arc. La portée garantit que tous les fils se terminent avant son retour.

Les lectures parallèles de données de la pile deviennent ainsi simples et sûres.

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()));
    });
}

Renvoyer des résultats depuis une portée

Les fils délimités renvoient également des valeurs par l’intermédiaire de leurs poignées. Vous attendez leur résultat dans la portée pour rassembler les résultats.

Comme la portée bloque jusqu’à la fin de l’exécution, les données empruntées restent valides pendant toute cette durée.

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);
}

N’oubliez pas d’attendre les résultats

Si vous abandonnez une JoinHandle sans attendre son résultat, le fil devient détaché. Il continue de s’exécuter, mais vous perdez son résultat et tout moyen d’attendre sa fin.

Le processus peut également se terminer avant le fil détaché. Attendez le résultat lorsque vous en avez besoin ou lorsque vous devez garantir la fin de l’exécution.

Vérification rapide

Testez votre compréhension de l’attente des résultats et de leur rassemblement.

Récapitulatif

Vous avez appris que join renvoie un Result contenant la valeur du fil ou l’information de panique. Lancez d’abord tous les fils, puis attendez leurs résultats pour conserver le parallélisme.

Vous pouvez rassembler les résultats dans un Vec, les réduire ou les ajouter à un Arc<Mutex<Vec>> partagé. Les fils délimités empruntent les données locales en toute sécurité, et l’abandon d’une poignée détache le fil.

Vous disposez maintenant des outils essentiels pour utiliser les fils et l’état partagé en Rust.

Questions Fréquemment Posées

La leçon « Rejoindre les threads et recueillir les résultats » est-elle gratuite ?

Oui — le texte complet de « Rejoindre les threads et recueillir les résultats » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Learn Rust Coding, passe à CoddyKit PRO. Le cours Learn Rust Coding comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Rejoindre les threads et recueillir les résultats » ?

Attendez les threads et rassemblez la sortie. Tu pratiques Learn Rust Coding avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Learn Rust Coding ?

Aucune expérience préalable n'est requise. Learn Rust Coding sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Rejoindre les threads et recueillir les résultats » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Learn Rust Coding ?

Oui. Chaque leçon Learn Rust Coding inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Créer des threads
  2. Déplacer des données dans des threads
  3. Partager avec Arc et Mutex
  4. Rejoindre les threads et recueillir les résultats
← Retour à Learn Rust Coding