非同期チャネル

いくつかのクレートは非同期チャネルをサポートしています。たとえば tokio です。

// 著作権 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0

use tokio::sync::mpsc;

async fn ping_handler(mut input: mpsc::Receiver<()>) {
    let mut count: usize = 0;

    while let Some(_) = input.recv().await {
        count += 1;
        println!("Received {count} pings so far.");
    }

    println!("ping_handler complete");
}

#[tokio::main]
async fn main() {
    let (sender, receiver) = mpsc::channel(32);
    let ping_handler_task = tokio::spawn(ping_handler(receiver));
    for i in 0..10 {
        sender.send(()).await.expect("Failed to send ping.");
        println!("Sent {} pings so far.", i + 1);
    }

    drop(sender);
    ping_handler_task.await.expect("Something went wrong in ping handler task.");
}
  • チャネルサイズを 3 に変更して、実行にどのような影響があるかを確認してください。

  • 全体として、インターフェースは 午前のクラス で見た sync チャネルに似ています。

  • std::mem::drop 呼び出しを削除してみてください。何が起こりますか?なぜですか?

  • Flume クレートには、syncasyncsend および recv の両方を実装したチャネルがあります。これは、IO と重い CPU 処理タスクの両方を含む複雑なアプリケーションで便利です。

  • async チャネルを扱うことが望ましい理由は、他の future と組み合わせて、複雑な制御フローを作成できる点にあります。