[rust学习]三、 rust中的并发 (TODO)
一、线程间通信方式: channel
1 use std::sync::mpsc; 2 use std::thread; 3 4 fn main() { 5 let (tx, rx) = mpsc::channel(); 6 7 thread::spawn(move || { 8 let val = String::from("hi"); 9 tx.send(val).unwrap(); 10 // 下面这一行会编译报错,因为变量val的所有权已经通过tx.send发生了转移 11 println!("val is {}", val); 12 }); 13 14 let received = rx.recv().unwrap(); 15 println!("Got: {}", received); 16 } 17
1. 特点: 多生产者单消费者、会转移所有权、
二、互斥锁:Mutex
Cargo.toml 文件: // 引入futures的crate, [dependencies] futures={version="0.3.28"}
1 use std::ops::DerefMut; 2 use std::sync::{Arc, Mutex}; 3 use std::thread; 4 use std::time::Duration; 5 6 // mutex死锁测试 7 fn main() { 8 // 用Mutex来模拟死锁 9 execute_mutex_lock(); 10 11 } 12 13 fn execute_mutex_lock(){ 14 // 这里使用的rust的Mutex 15 let lock= Arc::new(Mutex::new(0)); 16 let lock_ref= Arc::clone(&lock); 17 let t =thread::spawn(move || { 18 let mut v= lock_ref.lock().unwrap(); 19 println!("子线程:获取lock成功,v:{}",v); 20 *v.deref_mut()+=1; 21 let mut v= lock_ref.lock().unwrap(); 22 // 模拟线程t锁未释放,再次进行lock。 由于Mutex.lock( ) 是不可重入的、没有限制的、自旋锁,所以下面这句话永远不会打印出来,因为在上面那行就已经造成死锁了。 23 println!("子线程:再次获取lock成功,v:{}",v); 24 thread::sleep(Duration::from_secs(1)) 25 }); 26 t.join().unwrap(); 27 let v = lock.lock().unwrap(); 28 println!("主线程:v:{}",v); 29 }
1. 特点: rust中的Mutex是不可重入、自旋的互斥锁。 Mutex进行加锁有两个函数: lock、try_lock 。 其中lock函数会无线的自旋,所以如果获取不到锁就一直等待,而try_lock则是尝试获取一次锁,如果获取锁失败则会返回一个Error。这两种加锁方式按需使用即可。
三、Rc的兄弟Arc (todo:)