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, 所以引用可以被線程共享