Rust での await
この記事では、Rust での await
の意味を学びます。
Rust で await
async-await
は、一時停止し、実行時に制御を放棄して、中断したところから実行を再開できる関数を作成するための手法です。通常、これらの一時停止は I / O を待機するために使用されますが、さまざまな目的に使用できます。
async-await
は、JavaScript または C# でおなじみかもしれません。ただし、Rust の機能の実装には、いくつかの重要な変更があります。
async-await
を利用するには、fn
を async fn
に置き換える必要があります。
async fn new_fxn() -> u32 { .. }
従来の関数とは対照的に、async fn
を呼び出してもすぐには効果がありません。代わりに future
を返します。
計算は中断され、実行されるのを待っています。 .await
演算子を使用して future
を実行します。
async fn second_fxn () {
let future = new_fxn();
let result: u32 = future.await;
...
}
この例は、Rust と他の言語の最初の違いを示しています。future を待つのではなく、future.await
と記述します。この構文は、Rust の ?
とより適切に相互作用します。I/O で一般的なエラーを伝播するための演算子。
future.await?
と書くことができます欠点を負い、たくさんの結果を待つために。さらに、チェーンの方法を簡単にするという利点があります。
await
という用語は、非同期関数のコンテキスト内でのみ使用でき、非同期関数のみを待機できます。
Rust の future
は緩いです。デフォルトでは、最初のポーリングが実行されるまでは何もしません。future
を待つとき、それは調査されます。
たとえば、プログラムの開始時に future
を返す関数を呼び出したが、プログラムの終了まで await
しない場合、実際のリクエストは await
するまで実行されません。
例:
use std::thread;
use tokio::time::{sleep, Duration};
use futures::future;
#[tokio::main]
async fn main(){
let mut await_demo = Vec::new();
for count in 1..=5
{
await_demo.push(tokio::spawn(async move{
println!("Start the thread {count}, id= {:?}", thread::current().id());
sleep (Duration::from_millis(5000)).await;
println!("end the thread {count}, id = {:?})", thread::current().id());
}));
}
future::join_all (await_demo).await;
}
最初に、5つの futures
(5つの async
ブロック)が作成され、各 future
が sleep
future を作成し、その上で await
を呼び出します。これらの future
は同時に存在します。
各ブロックには、await
の前後にスレッド ID が表示されます。
出力:
Standard Output
Start the thread 1, id= ThreadId(2)
Start the thread 3, id= ThreadId(2)
Start the thread 4, id= ThreadId(2)
Start the thread 5, id= ThreadId(2)
Start the thread 2, id= ThreadId(3)
end the thread 2, id = ThreadId(2))
end the thread 3, id = ThreadId(3))
end the thread 1, id = ThreadId(3))
end the thread 4, id = ThreadId(3))
end the thread 5, id = ThreadId(3))