¡Bienvenidos de nuevo a Rustaceo.es! En este artículo exploraremos cómo manejar la concurrencia en Rust utilizando threads y mensajería. Rust nos proporciona herramientas seguras y eficientes para ejecutar múltiples tareas en paralelo sin los errores comunes de la programación concurrente.
🚀 Introducción a la concurrencia en Rust #
La concurrencia nos permite ejecutar múltiples tareas simultáneamente, mejorando el rendimiento de nuestras aplicaciones. Sin embargo, en muchos lenguajes esto puede ser peligroso debido a:
- Condiciones de carrera: Acceso simultáneo a datos sin sincronización.
- Interbloqueos (deadlocks): Hilos esperando indefinidamente por recursos bloqueados.
- Accesos no controlados a memoria: Datos corruptos por acceso no seguro.
Rust soluciona estos problemas con su modelo de propiedad y sistema de tipos, asegurando la seguridad en tiempo de compilación.
🧵 Creación de threads en Rust #
Podemos crear nuevos hilos fácilmente usando std::thread::spawn
.
📌 Ejemplo: creación de un hilo secundario #
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
crea un nuevo hilo. 🔹 join()
asegura que el hilo secundario termine antes de continuar.
📬 Comunicación segura entre hilos con mpsc
#
El modelo “pasar mensajes” usa mpsc::channel
para la comunicación entre hilos de manera segura.
📌 Ejemplo: envío de mensajes entre hilos #
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let mensaje = String::from("¡Hola desde otro hilo!");
tx.send(mensaje).unwrap();
});
let recibido = rx.recv().unwrap();
println!("Mensaje recibido: {}", recibido);
}
🔹 mpsc::channel
crea un canal de comunicación. 🔹 tx.send()
envía un mensaje desde el hilo secundario. 🔹 rx.recv()
recibe el mensaje en el hilo principal.
🔒 Compartición segura de datos con arc
y mutex
#
Cuando múltiples hilos necesitan modificar datos compartidos, usamos Arc<Mutex<T>>
para mantener la seguridad.
📌 Ejemplo: contador compartido entre hilos #
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
(Atomic Reference Counter): Permite múltiples propietarios del Mutex
sin violar reglas de propiedad. 🔹 Mutex
(Mutual Exclusion): Evita condiciones de carrera en datos compartidos.
🏆 Conclusión #
Rust ofrece herramientas seguras y eficientes para manejar threads y comunicación entre hilos, evitando errores comunes de la programación concurrente.
✔ Threads (std::thread
): Fácil manejo de múltiples hilos. ✔ Mensajería con mpsc
: Comunicación sin necesidad de memoria compartida. ✔ Arc<Mutex<T>>
: Sincronización segura de datos.
🔮 Próximo paso: Explora cómo combinar estos conceptos en aplicaciones reales como servidores web concurrentes o procesamiento paralelo.
¡Hasta la próxima, Rustaceos!