Асинхронні канали
Кілька крейтів підтримують асинхронні канали. Наприклад tokio:
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!("Отримано {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, так іasyncsendіrecv. Це може бути зручно для складних програм, що використовують як ввід-вивід, так і важкі процесорні завдання. -
Що робить роботу з
asyncканалами більш кращою, так це можливість комбінувати їх з іншимиfuture, щоб об’єднувати їх і створювати складні потоки управління.