La API de Mutex<T>
{=html}
Como ejemplo de cómo usar un mutex, comenzaremos por usarlo en un contexto de un solo hilo, como se muestra en la Lista 16-12.
Nombre de archivo: src/main.rs
use std::sync::Mutex;
fn main() {
1 let m = Mutex::new(5);
{
2 let mut num = m.lock().unwrap();
3 *num = 6;
4 }
5 println!("m = {:?}", m);
}
Lista 16-12: Explorando la API de Mutex<T>
en un contexto de un solo hilo para mayor simplicidad
Como con muchos tipos, creamos un Mutex<T>
usando la función asociada new
[1]. Para acceder a los datos dentro del mutex, usamos el método lock
para adquirir el cerrojo [2]. Esta llamada bloqueará el hilo actual, por lo que no podrá realizar ningún trabajo hasta que sea su turno para tener el cerrojo.
La llamada a lock
fallaría si otro hilo que tiene el cerrojo se descontrolara. En ese caso, nadie podría obtener el cerrojo, por lo que hemos elegido unwrap
y que este hilo se descontrolara si estamos en esa situación.
Después de haber adquirido el cerrojo, podemos tratar el valor devuelto, denominado num
en este caso, como una referencia mutable a los datos dentro. El sistema de tipos garantiza que adquiramos un cerrojo antes de usar el valor en m
. El tipo de m
es Mutex<i32>
, no i32
, por lo que debemos llamar a lock
para poder usar el valor i32
. No podemos olvidarlo; el sistema de tipos no nos permitirá acceder al i32
interno de otra manera.
Como es de esperar, Mutex<T>
es un puntero inteligente. Más precisamente, la llamada a lock
devuelve un puntero inteligente llamado MutexGuard
, envuelto en un LockResult
que manejamos con la llamada a unwrap
. El puntero inteligente MutexGuard
implementa Deref
para apuntar a nuestros datos internos; el puntero inteligente también tiene una implementación de Drop
que libera el cerrojo automáticamente cuando un MutexGuard
sale del ámbito, lo que sucede al final del ámbito interno [4]. Como resultado, no corremos el riesgo de olvidar liberar el cerrojo y bloquear el mutex para que no pueda ser usado por otros hilos porque la liberación del cerrojo se produce automáticamente.
Después de liberar el cerrojo, podemos imprimir el valor del mutex y ver que pudimos cambiar el i32
interno a 6
[5].