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

 

posted on 2020-12-28 11:10  tycoon3  阅读(868)  评论(0编辑  收藏  举报

导航