Asyncチャネル

Several crates have support for asynchronous channels. For instance tokio:

use tokio::sync::mpsc::{self, Receiver};

async fn ping_handler(mut input: 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クレートにはsyncasyncsendrecvの両方を実装するチャネルがあります。 これは入出力と重いCPUの処理のタスクの両方を含む、複雑なアプリケーションで便利です。

  • asyncチャネルを扱うことを好ましくするのは、チャネルと繋げるためにや、複雑なコントロールフローを作るために、チャネルを他のfutureと繋げられることです。