Rust de los fundamentos al dominio — Lección 9
Configuración de simultaneidad con subprocesos, canales y mutexes
Los artículos escritos en este blog fueron creados con el objetivo de enseñar. Además, la información del artículo puede ser incorrecta, así que tenga cuidado.
Rust restringe el acceso compartido a tipos, lo que puede crear carreras de datos. Incluso si utiliza subprocesos, canales o mutex, debe diseñar la terminación de la tarea y bloquear el alcance usted mismo.
Hilos iniciales y finales
use std::thread;
let handle = thread::spawn(|| {
load_world_data()
});
let world = handle
.join()
.expect("worker thread panicked");
El cierre pasado a spawn se ejecuta en un nuevo hilo. join espera a que se complete la tarea y regresa independientemente de que se produzca pánico como resultado.
Si un cierre utiliza un valor externo, debe sobrevivir al hilo, por lo que la propiedad a menudo se transfiere a move.
Enviar mensaje al canal
use std::sync::mpsc;
let (sender, receiver) = mpsc::channel();
thread::spawn(move || {
sender.send(String::from("Loaded")).unwrap();
});
if let Ok(message) = receiver.recv() {
println!("{message}");
}
Los canales mueven mensajes de una tarea a otra en lugar de compartir valores. Cuando todos los remitentes desaparecen, el receptor sabe que el canal está cerrado.
Arco y mutex
use std::sync::{Arc, Mutex};
let score = Arc::new(Mutex::new(0));
let worker_score = Arc::clone(&score);
let handle = thread::spawn(move || {
let mut value = worker_score.lock().unwrap();
*value += 10;
});
handle.join().unwrap();
Arc comparte la propiedad entre subprocesos y Mutex solo permite un acceso de cambio a la vez. Mantener un candado durante mucho tiempo o adquirir varios candados en un orden diferente puede provocar un rendimiento deficiente y bloqueos.
La concurrencia no se trata de aumentar el número de subprocesos. Después de reducir el estado compartido y definir los límites de los mensajes, es necesario medir el tamaño de la operación y la latencia.