Programmation asynchrone en Rust : guide complet 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 à la programmation asynchrone en Rust



La programmation asynchrone est une approche qui permet à votre application d'exécuter efficacement plusieurs tâches simultanément sans bloquer le thread d'exécution principal. En Rust, cette approche est implémentée via le modèle async/await, qui garantit la sécurité mémoire et les hautes performances caractéristiques du langage.



Contrairement au multithreading traditionnel, le code asynchrone fonctionne au sein d'un ou plusieurs threads, en basculant entre les tâches pendant les périodes d'attente (par exemple, les entrées-sorties ou les requêtes réseau). Cela le rend idéal pour créer des serveurs web à forte charge, des applications réseau et des outils de traitement de données.



Dans cet article, nous allons explorer les bases de la programmation asynchrone en Rust : des concepts clés aux exemples pratiques. Vous apprendrez comment fonctionnent Future, async et await, découvrirez le runtime populaire Tokio et écrirez votre premier projet asynchrone.



Concepts fondamentaux : Future, async et await



Qu'est-ce qu'un Future ?



En Rust, une tâche asynchrone est représentée par le trait Future. Un Future est une valeur qui peut ne pas être encore prête, mais qui sera obtenue dans le futur. Chaque Future possède une méthode poll qui vérifie si la tâche est terminée. Si la tâche est toujours en cours d'exécution, elle retourne Pending ; si elle est terminée, elle retourne Ready(value).



En lui-même, un Future n'effectue aucun travail. Il décrit seulement ce qui doit se produire. Pour exécuter du code asynchrone, un runtime est nécessaire — un exécuteur qui interroge les Future et gère leur exécution.



Les mots-clés async et await



Le mot-clé async transforme une fonction ordinaire en fonction asynchrone, qui retourne un Future. Par exemple :



async fn hello() -> String {    "Привет, мир!".to_string()}


Pour obtenir le résultat d'un Future, on utilise .await. Il suspend l'exécution de la fonction actuelle jusqu'à ce que le Future soit terminé :



let result = hello().await;println!("{}", result);


Important : .await ne peut être utilisé qu'à l'intérieur d'une fonction asynchrone ou d'un bloc async {}.



Cycle de vie d'une tâche asynchrone



  • Création d'un Future (appel d'une fonction asynchrone).
  • Transmission du Future au runtime pour exécution.
  • Le runtime interroge le Future via poll.
  • Si la tâche est bloquée (attente d'E/S), le runtime bascule vers une autre tâche.
  • Lorsque le résultat est prêt, le Future retourne Ready.


Écosystème : Tokio et async-std



Pour travailler avec du code asynchrone en Rust, on utilise des runtimes asynchrones. Les deux plus populaires sont Tokio et async-std.



Tokio



Tokio est le standard industriel pour la programmation asynchrone en Rust. Il fournit un ordonnanceur multithread, des entrées-sorties asynchrones, des minuteurs, de la synchronisation et des protocoles réseau. La plupart des grands projets (par exemple, Hyper, Tonic, Axum) sont construits sur Tokio.



Pour commencer avec Tokio, ajoutez la dépendance dans Cargo.toml :



[dependencies]tokio = { version = "1", features = ["full"] }


La macro principale pour lancer du code asynchrone est #[tokio::main] :



#[tokio::main]async fn main() {    println!("Hello from Tokio!");}


async-std



async-std est un runtime alternatif qui cherche à ressembler le plus possible à la bibliothèque standard de Rust. Il est plus simple pour les débutants, mais moins populaire en production.



Exemple

Blogs

Book Recommendations