Mutex
意為互斥對象,用來保護(hù)共享數(shù)據(jù)。Mutex 有下面幾個特征:
Mutex
會等待獲取鎖令牌(token),在等待過程中,會阻塞線程。直到鎖令牌得到。同時只有一個線程的 Mutex
對象獲取到鎖;Mutex
通過 .lock()
或 .try_lock()
來嘗試得到鎖令牌,被保護(hù)的對象,必須通過這兩個方法返回的 RAII
守衛(wèi)來調(diào)用,不能直接操作;RAII
守衛(wèi)作用域結(jié)束后,鎖會自動解開;Mutex
一般和 Arc
配合使用。示例:
use std::sync::{Arc, Mutex};
use std::thread;
use std::sync::mpsc::channel;
const N: usize = 10;
// Spawn a few threads to increment a shared variable (non-atomically), and
// let the main thread know once all increments are done.
//
// Here we're using an Arc to share memory among threads, and the data inside
// the Arc is protected with a mutex.
let data = Arc::new(Mutex::new(0));
let (tx, rx) = channel();
for _ in 0..10 {
let (data, tx) = (data.clone(), tx.clone());
thread::spawn(move || {
// The shared state can only be accessed once the lock is held.
// Our non-atomic increment is safe because we're the only thread
// which can access the shared state when the lock is held.
//
// We unwrap() the return value to assert that we are not expecting
// threads to ever fail while holding the lock.
let mut data = data.lock().unwrap();
*data += 1;
if *data == N {
tx.send(()).unwrap();
}
// the lock is unlocked here when `data` goes out of scope.
});
}
rx.recv().unwrap();
lock
與 try_lock
的區(qū)別.lock()
方法,會等待鎖令牌,等待的時候,會阻塞當(dāng)前線程。而 .try_lock()
方法,只是做一次嘗試操作,不會阻塞當(dāng)前線程。
當(dāng) .try_lock()
沒有獲取到鎖令牌時,會返回 Err
。因此,如果要使用 .try_lock()
,需要對返回值做仔細(xì)處理(比如,在一個循環(huán)檢查中)。
點評:Rust 的 Mutex 設(shè)計成一個對象,不同于 C 語言中的自旋鎖用兩條分開的語句的實現(xiàn),更安全,更美觀,也更好管理。
RwLock
翻譯成 讀寫鎖
。它的特點是:
比如:
use std::sync::RwLock;
let lock = RwLock::new(5);
// many reader locks can be held at once
{
let r1 = lock.read().unwrap();
let r2 = lock.read().unwrap();
assert_eq!(*r1, 5);
assert_eq!(*r2, 5);
} // read locks are dropped at this point
// only one write lock may be held, however
{
let mut w = lock.write().unwrap();
*w += 1;
assert_eq!(*w, 6);
} // write lock is dropped here
.read()
.try_read()
.write()
.try_write()
注意需要對 .try_read()
和 .try_write()
的返回值進(jìn)行判斷。