use std::sync::Mutex;
fn main() {
let m = Mutex::new(5); //Mutex<i32>, 智能指针
{
let mut num = m.lock().unwrap(); //等待,阻塞线程,
//返回MutexGuard, 智能指针,实施deref and drop
//如果其他线程锁定并惊慌,谁都得不到锁,所以直接unwrap
*num = 6; //num is &mut i32, deref
}
println!("m = {:?}", m);
}
cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/hello_world`
m = Mutex { data: 6 }
//进程共享mutex
use std::sync::Mutex;
use std::thread;
fn main() {
let counter = Mutex::new(0);
let mut handles = vec![];
for _ in 0..10 {
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap(); //错误,第一个线程搬走counter
*num += 1; //deref MutexGuard
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap()); //deref MutexGuard
}
cargo build
Compiling hello_world v0.1.0 (/data2/rust/mutex2)
error[E0382]: use of moved value: `counter`
--> src/main.rs:10:36
|
6 | let counter = Mutex::new(0);
| ------- move occurs because `counter` has type `std::sync::Mutex<i32>`, which does not implement the `Copy` trait
...
10 | let handle = thread::spawn(move || {
| ^^^^^^^ value moved into closure here, in previous iteration of loop
11 | let mut num = counter.lock().unwrap(); //错误,第一个线程搬走counter
| ------- use occurs due to use in closure
error: aborting due to previous error
For more information about this error, try `rustc --explain E0382`.
error: could not compile `hello_world`.
To learn more, run the command again with --verbose.
//进程共享mutex
use std::sync::Mutex;
use std::thread;
fn main() {
let counter = Mutex::new(0);
let mut handles = vec![];
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap(); //错误,第一个线程搬走counter
*num += 1; //deref MutexGuard
});
handles.push(handle);
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap()); //deref MutexGuard
}
cargo build
Compiling hello_world v0.1.0 (/data2/rust/mutex2)
error[E0382]: borrow of moved value: `counter`
--> src/main.rs:20:29
|
6 | let counter = Mutex::new(0);
| ------- move occurs because `counter` has type `std::sync::Mutex<i32>`, which does not implement the `Copy` trait
...
9 | let handle = thread::spawn(move || {
| ------- value moved into closure here
10 | let mut num = counter.lock().unwrap(); //错误,第一个线程搬走counter
| ------- variable moved due to use in closure
...
20 | println!("Result: {}", *counter.lock().unwrap()); //deref MutexGuard
| ^^^^^^^ value borrowed here after move
error: aborting due to previous error
For more information about this error, try `rustc --explain E0382`.
error: could not compile `hello_world`.
//使用Rc<T>共享
use std::rc::Rc;
use std::sync::Mutex;
use std::thread;
fn main() {
let counter = Rc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Rc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap(); //错误,Rc<T>不是线程安全
//Rc<T>.lock -> Mutex<>.lock
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());
}
Compiling hello_world v0.1.0 (/data2/rust/mutex3)
error[E0277]: `std::rc::Rc<std::sync::Mutex<i32>>` cannot be sent between threads safely
--> src/main.rs:11:22
|
11 | let handle = thread::spawn(move || {
| ______________________^^^^^^^^^^^^^_-
| | |
| | `std::rc::Rc<std::sync::Mutex<i32>>` cannot be sent between threads safely
12 | | let mut num = counter.lock().unwrap();
13 | | //错误,Rc<T>不是线程安全
14 | | //Rc<T>.lock -> Mutex<>.lock
15 | |
16 | | *num += 1; //deref MutexGuard
17 | | });
| |_________- within this `[closure@src/main.rs:11:36: 17:10 counter:std::rc::Rc<std::sync::Mutex<i32>>]`
|
= help: within `[closure@src/main.rs:11:36: 17:10 counter:std::rc::Rc<std::sync::Mutex<i32>>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::sync::Mutex<i32>>`
= note: required because it appears within the type `[closure@src/main.rs:11:36: 17:10 counter:std::rc::Rc<std::sync::Mutex<i32>>]`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `hello_world`.
To learn more, run the command again with --verbose.
[root@bogon mutex3]#
//使用Arc, Atomic Rc, 多线程版Rc,语法相同
use std::sync::{Mutex, Arc};
use std::thread;
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter); //counter不可变
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1; //可变,Mutex具有内部可变性,类似RefCell
//同时,Mutex也可能造成死锁,类似Rc的引用循环
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());
}
//实施了std::marker下的send的类型叫做send, 实施了sync的叫做sync
//send可以在线程间转移所有权,sync引用可以被线程共享,T是sync, 则&T is send
//大部分类型是send and sync
//Rc<T>, RefCell<T>, Cell<T>不是send也不是sync,
//Mutex是sync, 所以引用可以被线程共享