Asynchronität
Asynchrone Ausführungsreihenfolge
Abschnitt betitelt „Asynchrone Ausführungsreihenfolge“Betrachten Sie die folgende Funktion:
async fn print_letters() { let a = async { print!("A"); }; let b = async { print!("B"); }; let c = async { print!("C"); }; c.await; b.await; a.await;}Welche der folgenden Zeichenketten kann nach dem Ausführen von print_letters().await ausgegeben werden?
Dieses Programm hat ein deterministisches Verhalten. Die Ausgaben werden erst ausgeführt, wenn die asynchronen Blöcke awaited werden.
Die Blöcke werden in der Reihenfolge c/b/a awaited, daher wird das Programm nur CBA ausgeben.
Asynchrone Ausführungsinterleaving
Abschnitt betitelt „Asynchrone Ausführungsinterleaving“Angenommen, Sie haben eine Hilfsfunktion wait_all(a, b) mit dem folgenden Verhalten:
wait_allgarantiert, dassaundbvollständig ausgeführt werden.wait_allmacht keine Garantien bezüglich Fairness oder anfänglicher Ausführungsreihenfolge.
Betrachten Sie dann den folgenden Code:
async fn print_letters() { let fut1 = async { print!("A"); sleep().await; print!("B"); }; let fut2 = async { print!("C"); sleep().await; print!("D"); } wait_all(fut1, fut2).await;}Welche der folgenden Zeichenketten kann nach dem Ausführen von print_letters().await ausgegeben werden?
Das hypothetische wait_all-Primitiv ist wie join, aber mit weniger Garantien. Nur basierend auf der Spezifikation in diesem Problem ist jede Verschachtelung (Interleaving) der beiden Futures gültig. Die einzige ungültige Ausgabe ist eine, die die Programmausführungsreihenfolge umkehrt, d.h. DABC, bei der D vor C ausgegeben würde.
Asynchrone Kanal-Kommunikation
Abschnitt betitelt „Asynchrone Kanal-Kommunikation“Angenommen, Sie haben einen nicht-blockierenden und begrenzten Nachrichtenkanal channel(), was bedeutet, dass send ein Future zurückgibt, das abgeschlossen wird, sobald Kapazität im Kanal vorhanden ist.
Nehmen Sie außerdem an, Sie haben eine Funktion join(a, b), die fair auf den Abschluss beider Argumente wartet. Betrachten Sie dann diesen asynchronen Code:
let (tx, mut rx) = channel(16);let recv_fut = rx.recv();let send_fut = tx.send(0);let (n, _) = join(recv_fut, send_fut).await;println!("{}", n.unwrap());Was wird als Ergebnis der Ausführung dieses Codes geschehen?
Da der Kanal nicht-blockierend ist, können wir ein Empfangs-Future erstellen, bevor wir senden, ohne endlos zu schleifen.