互斥器

  1. 通道类似于单所有权的方式,值传递到通道后,发送者无法使用这个值
  2. 共享内存类似于多所有权,多个线程可以同时访问相同的内存位置
    互斥器: mutex
  3. 任意时刻,只允许一个线程来访问某些数据
  4. 互斥器使用的时候,需要先获取到锁,使用后需要释放锁(类似死锁,相互等待)
  5. Mutex是一个智能指针,lock调用返回一个叫做MutexGuard的智能指针,Mutex内部提供了drop方法,实现当MutexGuard离开作用域时自动释放锁。
1
2
3
4
5
6
7
8
9
10
11
12
//Mutex<T> 
use std::sync::Mutex;

fn main() {
let m = Mutex::new(5);

{
let mut num = m.lock().umwrap();//获取锁
*num = 6;
}//离开作用域自动释放
println!(" m = {:?}",m);
}

互斥器例子

  • 没有实现copy trait
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use std::sync::Mutex;
use std::thread;

fn main() {
let counter = Mutex::new(0);//没有实现copy trait
//之后会报错,因为多次尝试move,但是变量没有实现copy trait
let mut handles = vec![];

for _ in 0..10 {
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num +=1;
});
handles.push(handle);

}
for handle in handles {
handle.join().unwrap();
}
println!("result = {}",*counter.lock().unwrap());
}
  • 正解:使用Rc指针共享内存数据,但是Rc在线程之间不能够安全的发送,和RefCell适用于单线程
    rust提供了在线程之间安全共享的叫做arc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
use std::sync::Mutex;
use std::thread;
//use std::rc::Rc;
use std::sync::Arc;

fn main() {
//let counter = Rc::new(Mutex::new(0));
//let counter = Mutex::new(0);//没有实现copy trait
//之后会报错,因为多次尝试move,但是变量没有实现copy trait
let mut handles = vec![];
let counter = Arc::new(Mutex::new(0));

for _ in 0..10 {
let cnt = Rc::clone(&counter);
let handle = thread::spawn(move || {
let mut num =cnt.lock().unwrap();
*num +=1;
});
handles.push(handle);

}
for handle in handles {
handle.join().unwrap();
}
println!("result = {}",*counter.lock().unwrap());
}