Rustでの非同期処理(async/await)

Rustの組み込み用のフレームワークにembassyがありますが、そのサンプルコードの中では非同期処理が使われているので、概略を見てみる

https://qiita.com/Kumassy/items/fec47952d70b5073b1b7

参考はちょっと古いですが、上記のリンクですが、tokioのバージョンでタイマー待ちの処理が変わっているので最新に合わせてコードを変えています

<環境>

・M1 Macbook Air

・rustc 1.82.0

・tokio = { version = “1.42”, features = [“full”] }
#[tokio::main]はコンパイル時に展開されて、
Rustがデフォルトでは持っていない非同期処理を可能とする
<サンプルコード>
//
// original from https://qiita.com/Kumassy/items/fec47952d70b5073b1b7
//
// [dependencies]
// tokio = { version = "1.42", features = ["full"] }
use std::{thread, time};
use tokio::time::{sleep, Duration};

async fn hello() -> String {
    let one_sec = time::Duration::from_millis(1000);
    // in case of async application, it looks better to use tokio::time crate
    // delay_for : before tokio 0.2
    sleep(Duration::from_millis(1000)).await;
    thread::sleep(one_sec);

    "hello, async fn".to_string()
}

// tokio: to support async runtime
#[tokio::main]
// the async keyword of the fn main() is necessary
async fn main() {
    // excute sysnc function and wait completion
    let greeting: String = hello().await;
    println!("{}", greeting);

    // new task create(spawn)
    // return the type Result
    // 
    let handle = tokio::spawn(async {
        sleep(Duration::from_millis(1000)).await;
        "spawn thread elapsed one second".to_string()
    });

    // define async block
    //
    let world = async {
        let one_sec = time::Duration::from_millis(1000);
        thread::sleep(one_sec);

        println!("hello, async block");
    };

    // rcv spwan thread return
    let result: String = handle.await.unwrap();
    println!("{}", result);

    // async block call and wait
    world.await;

    // wait to avoid main thread terminate before spawn task complete
    sleep(Duration::from_millis(1500)).await;
}

やっていること、

① async fn hello()での非同期処理

② asyncブロック(let world)での非同期処理

③ async非同期タスク(tokio::spawn)からの戻り値(let result: String)の取得

<実行結果>

hello, async fn
spawn thread elapsed one second
hello, async block

複数箇所に時間待ちを入れているので、その時間待ちが入って出力されます

let one_sec = time::Duration::from_millis(1000); 
sleep(Duration::from_millis(1000)).await;

tokioには時間街のためのsleep()関数がありますが、std::time::Durationとの違いはsleep()関数自体がasyncブロックの如く機能するということなので使い分けは必要です

 

admin

カテゴリーRust