Programación asíncrona en Rust: guía completa para principiantes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción a la programación asíncrona en Rust



La programación asíncrona es un enfoque que permite que tu aplicación ejecute múltiples tareas simultáneamente de manera eficiente, sin bloquear el hilo principal de ejecución. En Rust, este enfoque se implementa a través del modelo async/await, que garantiza la seguridad de la memoria y el alto rendimiento característicos del lenguaje.



A diferencia del multihilo tradicional, el código asíncrono funciona dentro de uno o varios hilos, cambiando entre tareas durante los tiempos de espera (por ejemplo, entrada/salida o solicitudes de red). Esto lo hace ideal para crear servidores web de alta carga, aplicaciones de red y herramientas de procesamiento de datos.



En este artículo, analizaremos los fundamentos de la programación asíncrona en Rust: desde los conceptos clave hasta ejemplos prácticos. Aprenderás cómo funcionan Future, async y await, te familiarizarás con el popular runtime Tokio y escribirás tu primer proyecto asíncrono.



Conceptos principales: Future, async y await



¿Qué es Future?



En Rust, una tarea asíncrona está representada por el trait Future. Un Future es un valor que puede que aún no esté listo, pero se obtendrá en el futuro. Cada Future tiene un método poll que verifica si la tarea ha finalizado. Si la tarea aún se está ejecutando, devuelve Pending; si ha finalizado, devuelve Ready(value).



Por sí mismo, un Future no realiza ningún trabajo. Solo describe lo que debería suceder. Para ejecutar código asíncrono, se necesita un runtime: un ejecutor que consulta los Future y gestiona su ejecución.



Las palabras clave async y await



La palabra clave async transforma una función normal en una función asíncrona, que devuelve un Future. Por ejemplo:



async fn hello() -> String {    "¡Hola, mundo!".to_string()}


Para obtener el resultado de un Future, se utiliza .await. Esto pausa la ejecución de la función actual hasta que el Future se complete:



let result = hello().await;println!("{}", result);


Importante: .await solo se puede usar dentro de una función asíncrona o un bloque async {}.



Ciclo de vida de una tarea asíncrona



  • Creación del Future (llamada a una función asíncrona).
  • Pasar el Future al runtime para su ejecución.
  • El runtime consulta el Future a través de poll.
  • Si la tarea se bloquea (espera de E/S), el runtime cambia a otra tarea.
  • Cuando el resultado está listo, el Future devuelve Ready.


Ecosistema: Tokio y async-std



Para trabajar con código asíncrono en Rust, se utilizan runtimes asíncronos. Los dos más populares son Tokio y async-std.



Tokio



Tokio es el estándar industrial para la programación asíncrona en Rust. Proporciona un planificador multihilo, entrada/salida asíncrona, temporizadores, sincronización y protocolos de red. La mayoría de los proyectos grandes (por ejemplo, Hyper, Tonic, Axum) están construidos sobre Tokio.



Para empezar a trabajar con Tokio, añade la dependencia en tu Cargo.toml:



[dependencies]tokio = { version = "1", features = ["full"] }


La macro principal para ejecutar código asíncrono es #[tokio::main]:



#[tokio::main]async fn main() {    println!("Hello from Tokio!");}


async-std



async-std es un runtime alternativo que busca ser lo más parecido posible a la biblioteca estándar de Rust. Es más sencillo para principiantes, pero menos popular en producción.



Ejemplo

Blogs

Book Recommendations