Rust 第25节 并发
并发
thread::spawn() 创建新线程
参数是一个闭包,新线程执行的代码
rust
fn main() {
thread::spawn(||{
for i in 1..10 {
println!("son thread run :{}",i);
thread::sleep(Duration::from_micros(1));
}
});
for i in 1..5 {
println!("main thread run :{}",i);
thread::sleep(Duration::from_micros(1));
}
}
当主线程结束时,不管其他子线程是否结束,都会结束所有的子线程
可以使用 join()方法,等待子线程执行完
thread::spawn()会返回 joint_handler
move 闭包
从一个线程中,将所有权转移到另一个线程中
rust
let v = vec![11,13,14];
let handler = thread::spawn(move ||{ //将v的所有权移动到新线程中
println!("{:?}",v);
});
handler.join().unwrap();
使用消息传递来跨线程传递数据
channel
mpsc ::channel(多个生产者,一个消费者)
返回一个元组 发送端和接收端
rust
let (tx,rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hello");
tx.send(val).unwrap();
});
let recv = rx.recv().unwrap();
println!("main recved:{}",recv);
发送端的send方法
参数:想要发送的数据
返回值:Result<T,E>
如果有问题,就返回一个错误
接收端的方法:
recv:阻止当前线程执行,直到Channel中有值被送过来
有值返回Result<T,E>
通道关闭,返回错误
try_recv方法 不会阻塞,立即返回,有数据,返回OK,否则返回错误
所有权
发送后,数据的所有权已经转移
发送多条消息
rust
let (tx,rx) = mpsc::channel();
thread::spawn(move || {
let v = vec![String::from("message"),
String::from("from"),
String::from("thread"),
];
for i in v {
tx.send(i).unwrap();
thread::sleep(Duration::from_micros(1));
}
});
for receive in rx { //可以直接循环
println!("Get: {}",receive);
}
通过clone复制多个发送者
rust
let (tx,rx) = mpsc::channel();
let tx2 = mpsc::Sender::clone(&tx);
thread::spawn(move || {
let v = vec![String::from("1: message"),
String::from("1: from"),
String::from("1: thread"),
];
for i in v {
tx.send(i).unwrap();
thread::sleep(Duration::from_micros(1));
}
});
thread::spawn(move || {
let v = vec![String::from("2: message"),
String::from("2: from"),
String::from("2: thread"),
];
for i in v {
tx2.send(i).unwrap();
thread::sleep(Duration::from_micros(1));
}
});
for receive in rx {
println!("Get: {}",receive);
}
使用共享内存进行并发
使用mutex来每次只允许一个线程访问数据
mutex::new(数据) 来创建 mutex,他也是一个智能指针
在访问数据前,通过lock方法来获取锁
rust
let m = Mutex::new(5);
{
let mut num = m.lock().unwrap();//线程会阻塞到这里,直到获取到锁
*num = 6;
}
println!("m = {:?}",m);
多重所有权
想让多个线程都能使用mutex,需要将mutex的所有权进行多重多有权
并发使用的多重所有权为Arc,他和Rc的API完全一样
Arc是实现了原子级别的计数
Send 和 Sync trait
send :允许线程间转移所有权
sync : 允许多线程访问
手动实现这两个trait是无法保证安全的。