Asynchrone Programmierung ist ein wichtiges Konzept, das Sie als Rust-Entwickler kennen müssen.
Herkömmliche synchrone Programmiermodelle führen häufig zu Leistungsengpässen. Dies liegt daran, dass das Programm auf den Abschluss langsamer Vorgänge wartet, bevor es mit der nächsten Aufgabe fortfährt. Dies führt oft zu einer schlechten Ressourcennutzung und einer trägen Benutzererfahrung.
Mit der asynchronen Programmierung können Sie nicht blockierenden Code schreiben, der Systemressourcen effektiv nutzt. Durch die Nutzung der asynchronen Programmierung können Sie Apps entwerfen, die mehrere Aufgaben ausführen. Asynchrone Programmierung ist praktisch, um mehrere Netzwerkanfragen zu bearbeiten oder große Datenmengen zu verarbeiten, ohne den Ausführungsfluss zu blockieren.
Asynchrone Programmierung in Rust
Das asynchrone Programmiermodell von Rust ermöglicht Ihnen dies Schreiben Sie effizienten Rust-Code, der gleichzeitig ausgeführt wird ohne den Ausführungsfluss zu blockieren. Asynchrone Programmierung ist bei der Bearbeitung von E/A-Vorgängen, Netzwerkanforderungen und Aufgaben, bei denen auf externe Ressourcen gewartet werden muss, von Vorteil.
Sie können die asynchrone Programmierung in Ihren Rust-Apps auf verschiedene Arten implementieren. Dazu gehören Sprachfunktionen, Bibliotheken und die Tokio-Laufzeitumgebung.
Auch, Rusts Eigentumsmodell und Parallelitätsprimitive wie Kanäle und Sperren ermöglichen eine sichere und effiziente gleichzeitige Programmierung. Sie können diese Funktionen mit asynchroner Programmierung nutzen, um gleichzeitige Systeme zu erstellen, die gut skalierbar sind und mehrere CPU-Kerne nutzen.
Rusts asynchrone Programmierkonzepte
Futures bilden eine Grundlage für die asynchrone Programmierung in Rust. Eine Zukunft stellt eine asynchrone Berechnung dar, die noch nicht vollständig ausgeführt wurde.
Futures sind faul (sie werden nur bei Abfragen ausgeführt). Wenn Sie eine Zukunft nennen Umfrage() Mit dieser Methode wird geprüft, ob die Zukunft abgeschlossen ist oder zusätzliche Arbeiten erforderlich sind. Wenn die Zukunft nicht bereit ist, kehrt sie zurück Umfrage:: Ausstehend, was angibt, dass die Aufgabe für eine spätere Ausführung geplant werden soll. Wenn die Zukunft bereit ist, kehrt sie zurück Umfrage: Fertig mit dem resultierenden Wert.
Die Standard-Toolchain von Rust umfasst asynchrone I/O-Primitive, eine asynchrone Version von Datei-I/O, Netzwerk und Timer. Mit diesen Grundelementen können Sie E/A-Vorgänge asynchron ausführen. Dadurch wird vermieden, dass die Ausführung eines Programms blockiert wird, während auf den Abschluss von E/A-Aufgaben gewartet wird.
Mit der async/await-Syntax können Sie asynchronen Code schreiben, der synchronem Code ähnelt. Dadurch wird Ihr Code intuitiv und leicht zu warten.
Rusts Ansatz zur asynchronen Programmierung legt Wert auf Sicherheit und Leistung. Die Eigentums- und Ausleihregeln gewährleisten die Speichersicherheit und verhindern häufige Parallelitätsprobleme. Async/await-Syntax und Futures bieten eine intuitive Möglichkeit, asynchrone Arbeitsabläufe auszudrücken. Sie können eine Laufzeitumgebung eines Drittanbieters verwenden, um Aufgaben für eine effiziente Ausführung zu verwalten.
Sie können diese Sprachfunktionen, Bibliotheken und Laufzeit kombinieren, um hochleistungsfähigen Code zu schreiben. Es bietet ein leistungsstarkes und ergonomisches Framework für den Aufbau asynchroner Systeme. Dies macht Rust zu einer beliebten Wahl für Projekte, die eine effiziente Abwicklung von I/O-gebundenen Aufgaben und eine hohe Parallelität erfordern.
Rust Version 1.39 und spätere Versionen unterstützen keine asynchronen Vorgänge in der Standardbibliothek von Rust. Sie benötigen eine Kiste eines Drittanbieters, um das zu verwenden asynchron/erwarten Syntax zur Handhabung asynchroner Vorgänge in Rust. Sie können Pakete von Drittanbietern verwenden, z Tokio oder async-std um mit der async/await-Syntax zu arbeiten.
Asynchrone Programmierung mit Tokio
Tokio ist eine robuste asynchrone Laufzeit für Rust. Es bietet Funktionen zum Erstellen hochleistungsfähiger und skalierbarer Anwendungen. Mit Tokio können Sie die Leistungsfähigkeit der asynchronen Programmierung nutzen. Es bietet auch Funktionen zur Erweiterbarkeit.
Das Herzstück von Tokio ist das asynchrone Aufgabenplanungs- und Ausführungsmodell. Mit Tokio können Sie asynchronen Code mit der async/await-Syntax schreiben. Dies ermöglicht eine effiziente Nutzung der Systemressourcen und die gleichzeitige Ausführung von Aufgaben. Die Ereignisschleife von Tokio verwaltet die Aufgabenplanung effizient. Dies gewährleistet eine optimale Auslastung der CPU-Kerne und minimiert den Overhead beim Kontextwechsel.
Tokios Kombinatoren erleichtern die Koordination und Zusammensetzung von Aufgaben. Tokio bietet leistungsstarke Tools zur Aufgabenkoordination und -komposition. Sie können mit „Join“ auf den Abschluss mehrerer Aufgaben warten, mit „Select“ die erste abgeschlossene Aufgabe auswählen und mit „Race“ Aufgaben gegeneinander antreten lassen.
Ergänzen Sie die Tokio Kiste zu Ihrem Cargo.toml Abschnitt „Abhängigkeiten“ der Datei.
[dependencies]
tokio = { version = "1.9", features = ["full"] }
So können Sie die async/await-Syntax in Ihren Rust-Programmen mit Tokio verwenden:
use tokio:: time:: sleep;
use std:: time:: Duration;asyncfnhello_world() {
println!("Hello, ");
sleep(Duration:: from_secs(1)).await;
println!("World!");
}
#[tokio:: main]
asyncfnmain() {
hello_world().await;
}
Der Hallo Welt Die Funktion ist asynchron und kann daher verwendet werden erwarten Schlüsselwort, um die Ausführung anzuhalten, bis eine Zukunft gelöst ist. Der Hallo Welt Funktion druckt "Hallo, " zur Konsole. Der Dauer: from_secs (1) Der Funktionsaufruf unterbricht die Funktionsausführung für eine Sekunde. Der erwarten Das Schlüsselwort wartet auf den Abschluss der Sleep-Zukunft. Endlich, das Hallo Welt Funktion druckt "Welt!" zur Konsole.
Der hauptsächlich Funktion ist eine asynchrone Funktion mit dem #[tokio:: main] Attribut. Es bezeichnet die Hauptfunktion als Einstiegspunkt für die Tokio-Laufzeit. Der hello_world().await Führt die Funktion hello_world asynchron aus.
Aufgaben mit Tokio verzögern
Eine häufige Aufgabe bei der asynchronen Programmierung besteht darin, Verzögerungen zu verwenden oder Aufgaben so zu planen, dass sie in einem bestimmten Zeitbereich ausgeführt werden. Die Tokio-Laufzeit bietet einen Mechanismus zur Verwendung asynchroner Timer und Verzögerungen durch tokio:: Zeit Modul.
So können Sie einen Vorgang mit der Tokio-Laufzeit verzögern:
use std:: time:: Duration;
use tokio:: time:: sleep;asyncfndelayed_operation() {
println!("Performing delayed operation...");
sleep(Duration:: from_secs(2)).await;
println!("Delayed operation completed.");
}
#[tokio:: main]
asyncfnmain() {
println!("Starting...");
delayed_operation().await;
println!("Finished.");
}
Der verzögerte_Operation Die Funktion führt eine Verzögerung von zwei Sekunden mit ein schlafen Methode. Der verzögerte_Operation Die Funktion ist asynchron und kann daher die Ausführung mit „await“ anhalten, bis die Verzögerung abgeschlossen ist.
Fehlerbehandlung in asynchronen Programmen
Die Fehlerbehandlung im asynchronen Rust-Code umfasst die Verwendung von Ergebnis Typ und Umgang mit Rust-Fehlern mit dem ? Operator.
use tokio:: fs:: File;
use tokio:: io;
use tokio:: io::{AsyncReadExt};asyncfnread_file_contents() -> io::Result<String> {
letmut file = File:: open("file.txt").await?;
letmut contents = String::new();
file.read_to_string(&mut contents).await?;
Ok(contents)
}asyncfnprocess_file() -> io::Result {
let contents = read_file_contents().await?;
// Process the file contents
Ok(())
}
#[tokio:: main]
asyncfnmain() {
match process_file().await {
Ok(()) => println!("File processed successfully."),
Err(err) => eprintln!("Error processing file: {}", err),
}
}
Der read_file_contents Funktion gibt eine zurück io:: Ergebnis Dies stellt die Möglichkeit eines E/A-Fehlers dar. Durch die Verwendung der ? -Operator nach jedem asynchronen Vorgang wird die Tokio-Laufzeitumgebung Fehler im Aufrufstapel weitergeben.
Der hauptsächlich Funktion verarbeitet das Ergebnis mit a passen Anweisung, die einen Text basierend auf dem Ergebnis der Operation ausgibt.
Reqwest verwendet asynchrone Programmierung für HTTP-Vorgänge
Viele beliebte Crates, einschließlich Reqwest, verwenden Tokio, um asynchrone HTTP-Vorgänge bereitzustellen.
Sie können Tokio mit Reqwest verwenden, um mehrere HTTP-Anfragen zu stellen, ohne andere Aufgaben zu blockieren. Tokio kann Ihnen dabei helfen, Tausende gleichzeitiger Verbindungen zu verwalten und Ressourcen effizient zu verwalten.