Asynchrone Programmierung in Rust: Vollständiger Leitfaden mit Beispielen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Asynchrone Programmierung in Rust: Von den Grundlagen zu fortgeschrittenen Techniken



Moderne Anwendungen erfordern hohe Leistung und effiziente Arbeit mit I/O-Operationen. Rust, bekannt für seine Geschwindigkeit und Sicherheit, bietet ein leistungsstarkes Modell für asynchrone Programmierung. In diesem Leitfaden werden wir im Detail untersuchen, wie man async/await, die Bibliothek tokio und andere Werkzeuge verwendet, um schnelle und zuverlässige asynchrone Programme zu erstellen.



Was ist asynchrone Programmierung in Rust?



Asynchrone Programmierung ist ein Paradigma, das es ermöglicht, viele Aufgaben gleichzeitig auszuführen, ohne OS-Threads zu erstellen. Anstatt einen Thread beim Warten auf I/O (Dateilesen, HTTP-Anfrage) zu blockieren, wird eine asynchrone Funktion "pausiert" und übergibt die Kontrolle an andere Aufgaben. Rust implementiert dies durch Futures und den async/await-Mechanismus.



Schlüsselkonzepte:

  • Future — Ein Trait, der eine asynchrone Operation darstellt, die später abgeschlossen werden kann.
  • async/await — Syntaktischer Zucker für die Arbeit mit Futures.
  • Runtime (Executor) — Eine Laufzeitumgebung, die Futures abfragt und ausführt. Die beliebteste ist Tokio.
  • Task — Eine leichtgewichtige Arbeitseinheit, die von der Runtime verwaltet wird.


Das erste asynchrone Programm in Rust



Fügen Sie zunächst die Abhängigkeiten in Cargo.toml hinzu:



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


Jetzt schreiben wir einen einfachen asynchronen HTTP-Client:



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> { // Asynchrone GET-Anfrage let response = reqwest::get("https://jsonplaceholder.typicode.com/todos/1") .await?; // await pausiert die Ausführung, bis die Antwort eintrifft let todo: Todo = response.json().await?; // Asynchrone Deserialisierung println!("Aufgabe erhalten: {:#?}", todo); Ok(())}


Beachten Sie das Makro #[tokio::main] — es verwandelt die normale main-Funktion in einen asynchronen Einstiegspunkt und startet die Tokio-Runtime.



Erstellen asynchroner Funktionen und Arbeiten mit Tasks



Sie können Ihre eigenen asynchronen Funktionen mit dem Schlüsselwort async fn erstellen:



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

async fn simulate_work(id: u32, duration_secs: u64) -> String { println!("Aufgabe {} gestartet", id); sleep(Duration::from_secs(duration_secs)).await; // Asynchrone Verzögerung println!("Aufgabe {} abgeschlossen", id); format!("Ergebnis von Aufgabe {}", id)}

#[tokio::main]async fn main() { let start = std::time::Instant::now(); // Asynchrone Tasks erstellen let task1 = tokio::spawn(simulate_work(1, 2)); let task2 = tokio::spawn(simulate_work(2, 1)); let task3 = tokio::spawn(simulate_work(3, 3)); // Auf Abschluss aller Tasks warten let results = tokio::join!(task1, task2, task3); // Ergebnisse verarbeiten for result in &results { match result { Ok(msg) => println!("{}", msg), Err(e) => eprintln!("Fehler: {}", e), } } println!("Gesamtzeit: {:?}", start.elapsed()); // Wird in ~3 Sekunden ausgeführt, nicht in 6!}


Die Funktion tokio::spawn erstellt eine unabhängige asynchrone Aufgabe, die parallel zu anderen ausgeführt wird. tokio::join! wartet auf den Abschluss aller übergebenen Futures.



Fortgeschrittene Techn

Blogs

Buchempfehlungen