Colas de tareas en Rust: guía práctica con ejemplos de código

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: ¿por qué colas de tareas en Rust?

\n\n

En el desarrollo moderno de sistemas de alta carga, las colas de tareas (task queues) son un patrón fundamental. Permiten separar la generación de tareas y su ejecución, balancear la carga, escalar los workers y construir aplicaciones tolerantes a fallos. Rust, con su estricto control de memoria y la ausencia de un recolector de basura, ofrece capacidades únicas para implementar colas eficientes.

\n\n

En este artículo, analizaremos tres enfoques prácticos para trabajar con colas de tareas en Rust:

\n
    \n
  • Uso de canales estándar mpsc (multi-productor, único-consumidor);
  • \n
  • Colas multiproceso con la biblioteca crossbeam;
  • \n
  • Colas asíncronas con tokio.
  • \n
\n\n

Cada enfoque estará acompañado de un ejemplo de código funcional con explicaciones. Aprenderá a elegir la herramienta adecuada para cada tarea específica y a evitar errores típicos.

\n\n

1. Canales clásicos: std::sync::mpsc

\n\n

La biblioteca estándar de Rust proporciona el módulo std::sync::mpsc — una cola multiproceso con un único consumidor. Es la elección ideal cuando tiene varios productores (hilos que envían tareas) y un solo worker (hilo que las ejecuta).

\n\n

Ejemplo simple: pool de un solo worker

\n\n
use std::sync::mpsc;\nuse std::thread;\nuse std::time::Duration;\n\nfn main() {\n    // Creamos el canal: sender (remitente) y receiver (receptor)\n    let (tx, rx) = mpsc::channel::<String>();\n\n    // Iniciamos el hilo worker\n    let worker = thread::spawn(move || {\n        for task in rx {\n            println!("[Worker] Ejecutando tarea: {}", task);\n            thread::sleep(Duration::from_millis(500));\n            println!("[Worker] ¡Tarea '{}' completada!", task);\n        }\n    });\n\n    // Creamos varios productores (en un solo hilo por simplicidad)\n    let producer = thread::spawn(move || {\n        let tasks = vec![\n            "Procesar archivo A",\n            "Enviar correo electrónico",\n            "Actualizar base de datos",\n            "Generar informe",\n        ];\n        for task in tasks {\n            println!("[Productor] Enviando: {}", task);\n            tx.send(task.to_string()).unwrap();\n            thread::sleep(Duration::from_millis(200));\n        }\n    });\n\n    producer.join().unwrap();\n    // Después de que el sender (tx) sea destruido, el receiver (rx) recibirá None y el ciclo terminará\n    drop(tx); // cerramos el canal desde el lado del productor\n    worker.join().unwrap();\n}
\n\n

Características:

\n
    \n
  • El canal mpsc está almacenado en búfer: las tareas no bloquean al remitente hasta que el búfer esté lleno.
  • \n
  • Solo un receptor: es una limitación, pero garantiza simplicidad y seguridad en la concurrencia.
  • \n
  • Cuando todos los remitentes fallan, el canal se cierra automáticamente.
  • \n
\n\n

Varios workers: distribución manual

\n\n

Si necesita varios workers, mpsc no es adecuado directamente. La solución es crear un canal y varios hilos que compitan por obtener las tareas. Sin embargo, esto requiere cuidado: Receiver no implementa Sync, por lo que debe envolverse en un Mutex o Arc.

\n\n
use std::sync::{mpsc, Arc, Mutex};\nuse std::thread;\nuse std::time::Duration;\n\nfn main() {\n    let (tx, rx) = mpsc::channel::<String>();\n    let rx = Arc::new(Mutex::new(rx));\n\n    let mut workers = vec![];\n    for id in 0..3 {\n        let rx = Arc::clone(&rx);\n        let worker = thread::spawn(move || {\n            loop {\n                let task = {\n                    // Tomamos el mutex y obtenemos la tarea\n                    let rx = rx.lock().unwrap();\n                    rx.recv()\n                };\n                match task {\n                    Ok(task) => {\n                        println!("[Work                

Blogs

Book Recommendations