非同步管道

有些 Crate 支援非同步管道。例如 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 Crate 具有同時實作 syncasyncsendrecv 的管道。對於有 IO 和大量 CPU 處理工作的複雜應用程式,這相當便利。

  • 之所以較適合使用 async 管道,是因為這類管道能與其他 future 管道結合,進而建立複雜的控制流程。