Canales asíncronos
Varios crates admiten canales asíncronos. Por ejemplo, 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!("Se han recibido {count} pings hasta el momento.");
}
println!("ping_handler completo");
}
#[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("No se ha podido enviar el ping.");
println!("Se han enviado {} pings hasta ahora.", i + 1);
}
drop(sender);
ping_handler_task.await.expect("Se ha producido un error en la tarea del controlador de ping.");
}
This slide should take about 8 minutes.
-
Cambia el tamaño del canal a
3y comprueba cómo afecta a la ejecución. -
Overall, the interface is similar to the
syncchannels as seen in the morning class. -
Prueba a quitar la llamada a
std::mem::drop. ¿Qué sucede? ¿Por qué? -
El crate Flume tiene canales que implementan
syncyasync,sendyrecv. Esto puede resultar práctico para aplicaciones complejas con tareas de E/S y tareas pesadas de procesamiento de CPU. -
Es preferible trabajar con canales
asyncpor la capacidad de combinarlos con otrosfuturepara poder crear un flujo de control complejo.