Asynchronität in Rust wird durch Future realisiert – ein Objekt, das eine Arbeit darstellt, deren Ergebnis in der Zukunft erhalten wird. Funktionen, die mit async fn deklariert sind, geben eine anonyme Generatorstruktur zurück, die das Trait Future implementiert. Zum Ausführen von asynchronem Code wird ein Runtime (z.B. Tokio oder async-std) verwendet, da die Standardbibliothek keinen eingebauten Event Loop enthält.
Die Hauptmerkmale von Rust:
Beispiel:
use tokio::time::sleep; use std::time::Duration; async fn foo() { println!("Hallo"); sleep(Duration::from_secs(1)).await; println!("Welt!"); } #[tokio::main] async fn main() { foo().await; }
Kann eine asynchrone Funktion in Rust standardmäßig sofort bei ihrem Aufruf ausgeführt werden? Warum?
Antwort:
Nein. Der Aufruf von async fn gibt nicht das Ergebnis zurück, sondern ein Objekt vom Typ Future (Zustandsmaschine). Für die tatsächliche Ausführung ist es erforderlich, .await aufzurufen oder die Future an die Runtime zu übergeben. Der Aufruf selbst erstellt nur eine Beschreibung der Aufgabe, führt sie jedoch nicht aus.
Beispiel:
async fn answer() -> u32 { 42 } let fut = answer(); // hier gibt es keine Ausführung, nur Erstellung der future let result = fut.await; // die Ausführung beginnt hier
Geschichte
.await aufgerufen. Deshalb wurden die Haupt-Threads synchron ausgeführt, was zu einem Performance-Einbruch und einer Verdreifachung der Antwortzeiten führte.Geschichte
Geschichte
Ein Teammitglied vergaß die Send/Sync-Einschränkungen für die in Future verwendeten Typen. Beim Versuch, eine Future zwischen Threads zu teilen, stürzte die Anwendung mit einem Kompilierungsfehler ab, der die Implementierung von Send für eine bestimmte Struktur erforderte, was eine Überarbeitung der Architektur der Zustandsverwaltung erforderte.