¡Bienvenidos de nuevo a Rustaceo.es! En esta séptima semana nos sumergimos en los fundamentos y aplicaciones avanzadas de concurrencia y programación asíncrona en Rust. Desde la ejecución de múltiples hilos hasta el manejo eficiente de tareas asincrónicas, exploramos las herramientas que hacen de Rust un lenguaje seguro y eficiente para el desarrollo concurrente.
🚀 Principales temas cubiertos #
- Manejo de Threads en Rust: Creación y sincronización de hilos con
std::thread
. - Comunicación entre Hilos: Uso de
mpsc
para el paso seguro de mensajes. - Mutabilidad Compartida con
Arc
yMutex
: Acceso seguro a datos compartidos. - Programación Asíncrona con
async
yawait
: Ejecutando múltiples tareas concurrentemente sin bloqueo. - Construcción de un Servidor de Chat Asíncrono: Integrando Tokio para manejar múltiples conexiones simultáneamente.
🧵 Concurrencia con threads en Rust #
Rust nos permite crear hilos seguros usando std::thread::spawn
, evitando errores comunes en programación multihilo.
📌 Ejemplo: creación de threads #
use std::thread;
use std::time::Duration;
fn main() {
let handle = thread::spawn(|| {
for i in 1..5 {
println!("Hilo secundario: {}", i);
thread::sleep(Duration::from_millis(500));
}
});
for i in 1..3 {
println!("Hilo principal: {}", i);
thread::sleep(Duration::from_millis(500));
}
handle.join().unwrap();
}
✔ thread::spawn
: Lanza un nuevo hilo. ✔ join()
: Asegura que el hilo secundario termine antes de continuar.
📬 Comunicación segura entre hilos con mpsc
#
Para evitar el acceso directo a memoria compartida, usamos canales de mensajería (mpsc
):
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send("¡Hola desde otro hilo!").unwrap();
});
println!("Mensaje recibido: {}", rx.recv().unwrap());
}
✔ Evita condiciones de carrera al evitar compartir datos directamente.
🔒 Arc
y mutex
: sincronización de datos compartidos
#
Cuando los hilos deben acceder a una variable compartida, combinamos Arc
con Mutex
para garantizar seguridad.
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let contador = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..5 {
let contador = Arc::clone(&contador);
let handle = thread::spawn(move || {
let mut num = contador.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Valor final del contador: {}", *contador.lock().unwrap());
}
✔ Arc
: Permite múltiples referencias a Mutex
. ✔ Mutex
: Evita condiciones de carrera al acceder a la variable compartida.
⚡ Programación asíncrona con async
y await
#
Rust nos permite ejecutar tareas concurrentemente sin bloquear el hilo principal.
use tokio::time::{sleep, Duration};
#[Tokio::main]
async fn main() {
let tarea1 = tokio::spawn(async {
sleep(Duration::from_secs(2)).await;
println!("Tarea 1 completada");
});
let tarea2 = tokio::spawn(async {
println!("Tarea 2 iniciada");
});
tarea1.await.unwrap();
tarea2.await.unwrap();
}
✔ Ejecuta múltiples tareas sin bloqueo. ✔ tokio::spawn
permite lanzar tareas asíncronas de manera eficiente.
🏗 Construcción de un servidor de chat asíncrono #
Combinamos todo lo aprendido para construir un servidor de chat que maneja múltiples clientes concurrentemente.
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::broadcast;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
#[Tokio::main]
async fn main() {
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
let (tx, _rx) = broadcast::channel(10);
println!("Servidor de chat en 127.0.0.1:8080");
loop {
let (socket, _) = listener.accept().await.unwrap();
let tx = tx.clone();
let rx = tx.subscribe();
tokio::spawn(async move {
manejar_cliente(socket, tx, rx).await;
});
}
}
✔ Manejo de múltiples conexiones sin bloqueo. ✔ Mensajería en tiempo real con broadcast::channel
.
🏆 Conclusión #
Esta semana exploramos cómo Rust maneja la concurrencia y programación asíncrona de manera segura y eficiente.
🎯 Resumen de lo aprendido: ✔ Hilos (std::thread
) para concurrencia básica. ✔ Mensajería con mpsc
para comunicación segura. ✔ Sincronización con Arc<Mutex<T>>
para datos compartidos. ✔ Programación asíncrona con async
/await
. ✔ Construcción de un servidor de chat asíncrono.
🔮 Próximo paso: Experimentar con arquitecturas asincrónicas avanzadas y optimizar el rendimiento de servidores concurrentes.
¡Hasta la próxima, Rustaceos!