Why was Mutex<T>
designed to need an Arc<T>
if the only reason to use a Mutex<T>
is for concurrent code, i.e. multiple threads? Wouldn't it be better to alias a Mutex<T>
to an atomic reference in the first place? I'm using https://doc.rust-lang.org/book/ch16-03-shared-state.html as reference.
Asked
Active
Viewed 3,903 times
6

Peter Hall
- 53,120
- 14
- 139
- 204

Lev
- 1,698
- 3
- 18
- 26
1 Answers
22
You don't need an Arc
to use a Mutex
. The signature of lock
(the most used method on a Mutex
) is pub fn lock(&self) -> LockResult<MutexGuard<T>>
which means you need a reference to the Mutex
.
The problem arises with the borrow-checker. It is not able to prove certain guarantees when passing a reference to threads which might outlive the original Mutex
. That's why you use Arc
which guarantees that the value inside lives as long as the last Arc
lives.
use lazy_static::lazy_static; // 1.3.0
use std::sync::Mutex;
use std::thread::spawn;
lazy_static! {
static ref M: Mutex<u32> = Mutex::new(5);
}
fn a(m: &Mutex<u32>) {
println!("{}", m.lock().unwrap());
}
fn b(m: &Mutex<u32>) {
println!("{}", m.lock().unwrap());
}
fn main() {
let t1 = spawn(|| a(&M));
let t2 = spawn(|| b(&M));
t1.join().unwrap();
t2.join().unwrap();
}

Shepmaster
- 388,571
- 95
- 1,107
- 1,366

hellow
- 12,430
- 7
- 56
- 79
-
1I think scoped threads are a more obvious use of a `Mutex` (or `RwLock` or `Atomic`) without reference counting: [How can I pass a reference to a stack variable to a thread?](https://stackoverflow.com/q/32750829/155423). – Shepmaster Jun 13 '19 at 14:04