Класс Mutex
Класс Mutex (mutual exclusion) представляет собой примитив синхронизации, который позволяет только одному потоку одновременно получать доступ к защищённым данным. Параметром тип Mutex принимает тип данных T, которые будут защищены. Доступ к данным осуществляется через методы lock и try_lock, возвращающие умный указатель MutexGuard.
Синтаксис
use std::sync::Mutex;
let mutex = Mutex::new(value);
Пример
Давайте создадим мьютекс, защищающий целое число, и изменим его значение из одного потока:
use std::sync::Mutex;
fn main()
{
let mutex = Mutex::new(5);
{
let mut guard = mutex.lock().unwrap();
*guard += 10;
}
let res = mutex.lock().unwrap();
println!("{}", *res);
}
Результат выполнения кода:
15
Пример
Давайте используем мьютекс для безопасного доступа к данным из нескольких потоков:
use std::sync::{Arc, Mutex};
use std::thread;
fn main()
{
let data = Arc::new(Mutex::new(vec![1, 2, 3, 4, 5]));
let mut handles = vec![];
for i in 0..3 {
let data = Arc::clone(&data);
let handle = thread::spawn(move || {
let mut guard = data.lock().unwrap();
guard.push(i + 6);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let res = data.lock().unwrap();
println!("{:?}", *res);
}
Результат выполнения кода:
[1, 2, 3, 4, 5, 6, 7, 8]
Пример
Давайте проверим метод try_lock, который пытается захватить мьютекс без блокировки потока:
use std::sync::Mutex;
fn main()
{
let mutex = Mutex::new("abcde");
let guard = mutex.lock().unwrap();
match mutex.try_lock() {
Ok(_) => println!("lock acquired"),
Err(_) => println!("lock failed"),
}
drop(guard);
match mutex.try_lock() {
Ok(res) => println!("{}", *res),
Err(_) => println!("lock failed"),
}
}
Результат выполнения кода:
"lock failed"
"abcde"
Смотрите также
-
метод
new,
который создаёт новый мьютекс с указанным значением -
метод
lock,
который захватывает мьютекс и возвращает MutexGuard -
метод
try_lock,
который пытается захватить мьютекс без блокировки -
метод
into_inner,
который извлекает значение из мьютекса