Rust编程语言之无畏并发并发Concurrent:程序的不同部分之间独立的执行(并发)Parallel:程序的不同部分同时运行(并行)Rust无畏并发:允许你编写没有细微Bug的代码,并在不引入新Bug的情况下易于重构注意:本文中的”并发“泛指concurrent和paralle
➜ cd rust
~/rust
➜ cargo new thread_demo
Created binary (application) `thread_demo` package
~/rust
➜ cd thread_demo
thread_demo on master [?] via 🦀 1.67.1
➜ c # code .
thread_demo on master [?] via 🦀 1.67.1
➜
use std::thread;
use std::time::Duration;
fn main() {
thread::spawn(|| {
for i in 1..10 {
println!("hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
for i in 1..5 {
println!("hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1)); // 暂停 1 毫秒
}
}
执行
thread_demo on master [?] is 📦 0.1.0 via 🦀 1.67.1
➜ cargo run
Compiling thread_demo v0.1.0 (/Users/qiaopengjun/rust/thread_demo)
Finished dev [unoptimized + debuginfo] target(s) in 0.65s
Running `target/debug/thread_demo`
hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the main thread!
hi number 2 from the spawned thread!
hi number 3 from the main thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 4 from the main thread!
hi number 5 from the spawned thread!
thread_demo on master [?] is 📦 0.1.0 via 🦀 1.67.1
➜
use std::thread;
use std::time::Duration;
fn main() {
let handle = thread::spawn(|| {
for i in 1..10 {
println!("hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
for i in 1..5 {
println!("hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1)); // 暂停 1 毫秒
}
handle.join().unwrap();
}
执行
thread_demo on master [?] is 📦 0.1.0 via 🦀 1.67.1
➜ cargo run
Compiling thread_demo v0.1.0 (/Users/qiaopengjun/rust/thread_demo)
Finished dev [unoptimized + debuginfo] target(s) in 0.75s
Running `target/debug/thread_demo`
hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 2 from the main thread!
hi number 3 from the spawned thread!
hi number 3 from the main thread!
hi number 4 from the spawned thread!
hi number 4 from the main thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!
thread_demo on master [?] is 📦 0.1.0 via 🦀 1.67.1
等分线程执行完继续执行主线程
use std::thread;
use std::time::Duration;
fn main() {
let handle = thread::spawn(|| {
for i in 1..10 {
println!("hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
handle.join().unwrap();
for i in 1..5 {
println!("hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1)); // 暂停 1 毫秒
}
}
运行
thread_demo on master [?] is 📦 0.1.0 via 🦀 1.67.1
➜ cargo run
Compiling thread_demo v0.1.0 (/Users/qiaopengjun/rust/thread_demo)
Finished dev [unoptimized + debuginfo] target(s) in 0.28s
Running `target/debug/thread_demo`
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!
hi number 1 from the main thread!
hi number 2 from the main thread!
hi number 3 from the main thread!
hi number 4 from the main thread!
thread_demo on master [?] is 📦 0.1.0 via 🦀 1.67.1
use std::thread;
fn main() {
let v = vec![1, 2, 3];
let handle = thread::spawn(|| { // 报错
println!("Here's a vector: {:?}", v);
});
// drop(v);
handle.join().unwrap();
}
修改后:
use std::thread;
fn main() {
let v = vec![1, 2, 3];
let handle = thread::spawn(move || {
println!("Here's a vector: {:?}", v);
});
// drop(v);
handle.join().unwrap();
}
mpsc::channel
函数来创建 Channel
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap();
});
let received = rx.recv().unwrap();
println!("Got: {}", received);
}
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap();
println!("val is {}", val) // 报错 借用了移动的值
});
let received = rx.recv().unwrap();
println!("Got: {}", received);
}
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("thread"),
];
for val in vals {
tx.send(val).unwrap();
thread::sleep(Duration::from_millis(1));
}
});
for received in rx {
println!("Got: {}", received);
}
}
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
let (tx, rx) = mpsc::channel();
let tx1 = mpsc::Sender::clone(&tx);
thread::spawn(move || {
let vals = vec![
String::from("1: hi"),
String::from("1: from"),
String::from("1: the"),
String::from("1: thread"),
];
for val in vals {
tx1.send(val).unwrap();
thread::sleep(Duration::from_millis(1));
}
});
thread::spawn(move || {
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("thread"),
];
for val in vals {
tx.send(val).unwrap();
thread::sleep(Duration::from_millis(1));
}
});
for received in rx {
println!("Got: {}", received);
}
}
Mutex<T>
的 APIMutex<T>
Mutex<T>
是一个智能指针use std::sync::Mutex;
fn main() {
let m = Mutex::new(5);
{
let mut num = m.lock().unwrap();
*num = 6;
}
println!("m = {:?}", m);
}
Mutex<T>
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();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());
}
use std::sync::Mutex;
use std::thread;
use std::rc::Rc;
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 || { // 报错 rc 只能用于单线程
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());
}
Arc<T>
来进行原子引用计数Arc<T>
和Rc<T>
类似,它可以用于并发情景
Arc<T>
?
Arc<T>
和Rc<T>
的API是相同的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);
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());
}
RefCell<T>
/Rc<T>
vs Muter<T>
/Arc<T>
Mutex<T>
提供了内部可变性,和 Cell 家族一样RefCell<T>
来改变 Rc<T>
里面的内容Mutex<T>
来改变 Arc<T>
里面的内容Mutex<T>
有死锁风险Rc<T>
没有实现 Send,它只用于单线程情景Rc<T>
不是 Sync 的RefCell<T>
和 Cell<T>
家族也不是 Sync的Mutex<T>
是Sync的未完待续...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!