Асинхронні канали

Кілька крейтів підтримують асинхронні канали. Наприклад 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!("Отримано {count} пінгів до цього часу.");
    }

    println!("ping_handler завершено");
}

#[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("Не вдалося надіслати пінг.");
        println!("Поки що надіслано {} пінгів.", i + 1);
    }

    drop(sender);
    ping_handler_task.await.expect("Щось пішло не так у завданні обробника пінгу.");
}
This slide should take about 8 minutes.
  • Змініть розмір каналу на 3 і подивіться, як це вплине на виконання.

  • Загалом, інтерфейс подібний до каналів sync, які ми бачили в ранковому класі.

  • Спробуйте видалити виклик std::mem::drop. Що сталося? Чому?

  • Крейт Flume має канали, які реалізують як sync, так і async send і recv. Це може бути зручно для складних програм, що використовують як ввід-вивід, так і важкі процесорні завдання.

  • Що робить роботу з async каналами більш кращою, так це можливість комбінувати їх з іншими future, щоб об'єднувати їх і створювати складні потоки управління.