Rust学习 mutex
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, 所以引用可以被线程共享
Result: 10