Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Асинхронные каналы

Несколько крейтов поддерживают асинхронные каналы. Например, tokio:

// Copyright 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.");
}
This slide should take about 8 minutes.
  • Измените размер канала на 3 и посмотрите, как это повлияет на выполнение.

  • В целом интерфейс похож на синхронные каналы, которые мы видели на утреннем занятии.

  • Попробуйте убрать вызов std::mem::drop. Что произойдёт? Почему?

  • Крейт Flume содержит каналы, которые реализуют и синхронные, и асинхронные send и recv. Это может быть удобно в сложных приложениях с задачами и вводом-выводом, и тяжёлой процессорной обработкой.

  • Работа с асинхронными каналами удобнее благодаря возможности комбинировать их с другими фьючерсами, чтобы создавать сложный поток управления.