Files d'attente de tâches en Rust : guide pratique pour débutants

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction aux files d'attente de tâches en Rust

\n\n

Les files d'attente de tâches sont l'un des modèles fondamentaux de la programmation concurrente. Elles permettent d'organiser efficacement le transfert de travail entre les threads, simplifiant ainsi l'architecture des applications. En Rust, avec son système strict de possession et de types, travailler avec des files d'attente nécessite une approche particulière, mais offre en retour une sécurité et des performances incroyables.

\n\n

Dans cet article, nous allons voir comment créer et utiliser des files d'attente de tâches en Rust à partir de zéro. Vous découvrirez les outils standards du langage, tels que les canaux mpsc (multi-producteur, mono-consommateur), et vous familiariserez avec les bibliothèques populaires pour le traitement asynchrone. Ce contenu est destiné aux développeurs débutants déjà familiers avec les bases de la syntaxe Rust.

\n\n

Les bases : qu'est-ce qu'une file d'attente de tâches et pourquoi en a-t-on besoin

\n\n

Une file d'attente de tâches est une structure de données fonctionnant selon le principe FIFO (First In, First Out). Dans le contexte du multithreading, elle permet à certains threads (producteurs) d'ajouter des tâches, et à d'autres (consommateurs) de les récupérer et de les exécuter.

\n\n

Les principaux avantages de l'utilisation des files d'attente :

\n\n
    \n
  • Séparation des responsabilités — la logique de génération des tâches est séparée de leur exécution.
  • \n
  • Équilibrage de charge — on peut lancer plusieurs threads consommateurs pour un traitement parallèle.
  • \n
  • Gestion du flux de données — la file d'attente lisse les pics de charge, évitant la surcharge du système.
  • \n
  • Simplicité des tests — chaque composant peut être testé isolément.
  • \n
\n\n

En Rust, la bibliothèque standard fournit le module std::sync::mpsc pour créer des canaux avec un seul récepteur. C'est un outil idéal pour commencer.

\n\n

Création d'une file d'attente simple avec mpsc

\n\n

Commençons par un exemple de base : un producteur envoie des nombres, un consommateur les traite.

\n\n
use std::sync::mpsc;\nuse std::thread;\nuse std::time::Duration;\n\nfn main() {\n    // Création du canal : tx — émetteur, rx — récepteur\n    let (tx, rx) = mpsc::channel();\n\n    // Lancement du thread producteur\n    thread::spawn(move || {\n        for i in 1..=5 {\n            println!("Envoi : {}", i);\n            tx.send(i).unwrap();\n            thread::sleep(Duration::from_millis(500));\n        }\n    });\n\n    // Thread consommateur (thread principal)\n    for received in rx {\n        println!("Reçu : {}", received);\n    }\n}\n
\n\n

Dans cet exemple, tx (transmetteur) peut être cloné pour plusieurs producteurs, tandis que rx (récepteur) est le seul consommateur. La méthode send retourne un Result que nous traitons avec unwrap() — dans un code réel, il faut gérer les erreurs plus correctement.

\n\n

Producteurs multiples

\n\n

Pour créer plusieurs threads producteurs, on clone l'émetteur :

\n\n
use std::sync::mpsc;\nuse std::thread;\n\nfn main() {\n    let (tx, rx) = mpsc::channel();\n    let tx1 = tx.clone();\n\n    thread::spawn(move || {\n        for i in 1..=3 {\n            tx1.send(format!("Thread 1 : message {}", i)).unwrap();\n        }\n    });\n\n    thread::spawn(move || {\n        for i in 1..=3 {\n            tx.send(format!("Thread 2 : message {}", i)).unwrap();\n        }\n    });\n\n    for received in rx {\n        println!("{}", received);\n    }\n}\n
\n\n

Notez que le tx original est déplacé dans le second thread, donc nous le clonons avant le déplacement.

\n\n

Techniques avancées : types de tâches et gestion des erreurs

\n\n

Dans les applications réelles, les tâches sont rarement de simples nombres. Ce sont souvent des structures contenant des données et de la logique. Voyons comment organiser une file d'attente avec des tâches de différents types.

\n\n

Énumération pour différents types de tâches

\n\n
use std::sync::mpsc;\nuse std::thread;\n\n#[derive(Debug)]\nenum Task {\n    Compute { a :                

Blogs

Book Recommendations