Programmation asynchrone en Rust : guide complet avec exemples

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

Programmation asynchrone en Rust : des bases aux techniques avancées



Les applications modernes exigent des performances élevées et une gestion efficace des opérations d'E/S. Rust, connu pour sa vitesse et sa sécurité, propose un modèle de programmation asynchrone puissant. Dans ce guide, nous allons détailler comment utiliser async/await, la bibliothèque tokio et d'autres outils pour créer des programmes asynchrones rapides et fiables.



Qu'est-ce que la programmation asynchrone en Rust ?



La programmation asynchrone est un paradigme qui permet d'exécuter plusieurs tâches simultanément sans créer de threads OS. Au lieu de bloquer un thread en attendant une opération d'E/S (lecture de fichier, requête HTTP), une fonction asynchrone se "met en pause" et cède le contrôle à d'autres tâches. Rust implémente cela via les Futures et le mécanisme async/await.



Concepts clés :

  • Future — un trait représentant une opération asynchrone qui peut se terminer plus tard.
  • async/await — du sucre syntaxique pour travailler avec les Futures.
  • Runtime (exécuteur) — l'environnement d'exécution qui interroge les Futures et les lance. Le plus populaire est Tokio.
  • Task — une unité de travail légère gérée par le Runtime.


Premier programme asynchrone en Rust



Pour commencer, ajoutez les dépendances dans Cargo.toml :



[dependencies]tokio = { version = "1", features = ["full"] }reqwest = { version = "0.12", features = ["json"] }serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"


Écrivons maintenant un simple client HTTP asynchrone :



use reqwest;use serde::Deserialize;

#[derive(Deserialize, Debug)]struct Todo { userId: u32, id: u32, title: String, completed: bool,}

#[tokio::main]async fn main() -> Result<(), Box> { // Requête GET asynchrone let response = reqwest::get("https://jsonplaceholder.typicode.com/todos/1") .await?; // await suspend l'exécution jusqu'à la réception de la réponse let todo: Todo = response.json().await?; // Désérialisation asynchrone println!("Tâche reçue : {:#?}", todo); Ok(())}


Remarquez la macro #[tokio::main] — elle transforme la fonction main classique en point d'entrée asynchrone, en lançant le Runtime Tokio.



Création de fonctions asynchrones et travail avec les tâches



Vous pouvez créer vos propres fonctions asynchrones avec le mot-clé async fn :



use std::time::Duration;use tokio::time::sleep;

async fn simulate_work(id: u32, duration_secs: u64) -> String { println!("Tâche {} commencée", id); sleep(Duration::from_secs(duration_secs)).await; // Délai asynchrone println!("Tâche {} terminée", id); format!("Résultat de la tâche {}", id)}

#[tokio::main]async fn main() { let start = std::time::Instant::now(); // Création de tâches asynchrones (tasks) let task1 = tokio::spawn(simulate_work(1, 2)); let task2 = tokio::spawn(simulate_work(2, 1)); let task3 = tokio::spawn(simulate_work(3, 3)); // Attente de la fin de toutes les tâches let results = tokio::join!(task1, task2, task3); // Traitement des résultats for result in &results { match result { Ok(msg) => println!("{}", msg), Err(e) => eprintln!("Erreur : {}", e), } } println!("Temps total : {:?}", start.elapsed()); // S'exécutera en ~3 secondes, pas en 6 !}


La fonction tokio::spawn crée une tâche asynchrone indépendante qui s'exécute en parallèle des autres. tokio::join! attend la fin de tous les futurs passés.



Techniques avancées

Blogs

Book Recommendations