文章目录
- Rust对多线程的支持
-
-
- std::thread::spawn创建线程
- [线程与 move 闭包](#线程与 move 闭包)
- 使用消息传递在线程间传送数据
-
- std::sync::mpsc::channel()
- [for received in rx接收](#for received in rx接收)
- 两个producer
-
- 共享状态并发
- 参考
Rust对多线程的支持
rust默认仅支持一对一线程,也就是说操作系统线程。
可以引入crate包来使用绿色线程。
std::thread::spawn创建线程
rust
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));
}
handle.join().unwrap();
}
编译
bash
cargo run
warning: unused `Result` that must be used
--> src/main.rs:17:5
|
17 | handle.join();
| ^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
|
17 | let _ = handle.join();
| +++++++
warning: `smartPtr` (bin "smartPtr") generated 1 warning
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/smartPtr`
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 main 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!
线程与 move 闭包
rust
use std::thread;
fn main() {
let v = vec![1, 2, 3];
let handle = thread::spawn(move || {
println!("Here's a vector: {:?}", v);
});
handle.join().unwrap();
}
编译
rust
cargo run
Blocking waiting for file lock on build directory
Compiling smartPtr v0.1.0 (/home/wangji/installer/rust/bobo/smartPtr)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 19.07s
Running `target/debug/smartPtr`
Here's a vector: [1, 2, 3]
使用消息传递在线程间传送数据
std::sync::mpsc::channel()
只支持多个生产者和一个消费者
rust
use std::sync::mpsc; //mpsc:multi-producer, single-consumer
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap();
});
// recv()会阻塞
// try_recv()是非阻塞,适合使用loop来尝试接收
let received = rx.recv().unwrap();
println!("Got: {}", received);
}
for received in rx接收
rust
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
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_secs(1));
}
});
// 当发送方tx结束了,接收方rx就会结束(for循环也会结束)
for received in rx {
println!("Got: {}", received);
}
}
两个producer
rust
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
// --snip--
let (tx, rx) = mpsc::channel();
let tx1 = tx.clone(); //tx和tx1都连接到mpsc::channel()
thread::spawn(move || {
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("thread"),
];
for val in vals {
tx1.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
thread::spawn(move || {
let vals = vec![
String::from("more"),
String::from("messages"),
String::from("for"),
String::from("you"),
];
for val in vals {
tx.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
for received in rx {
println!("Got: {}", received);
}
// --snip--
}
共享状态并发
std::sync::Mutex
rust
use std::sync::Mutex;
fn main() {
let m = Mutex::new(5);
{
// m.lock()会阻塞当前线程,获取锁位置
let mut num = m.lock().unwrap();
*num = 6;
// 退出时会自动释放锁
}
println!("m = {:?}", m);
}
编译及运行
bash
cargo run
Compiling smartPtr v0.1.0 (/home/wangji/installer/rust/bobo/smartPtr)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.57s
Running `target/debug/smartPtr`
m = Mutex { data: 6, poisoned: false, .. }
在多个线程间共享Mutex,使用std::sync::Arc
rust
use std::sync::Arc;
use std::sync::Mutex;
use std::thread;
fn main() {
// Mutex于Arc经常一起使用
// Rc::new可以让Mutex拥有多个所有者
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter); //Rc::clone不是真正的clone,只是增加引用计数
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap(); //counter.lock()可以获得可变的引用(类似于RefCell智能指针)
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());
}
编译
bash
cargo run
Compiling smartPtr v0.1.0 (/home/wangji/installer/rust/bobo/smartPtr)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 5.85s
Running `target/debug/smartPtr`
Result: 10