使用 spawn 创建新线程
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));
}
}
使用 join 等待所有线程结束
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() 调用会等待直到新建线程执行完毕
//
handle.join().unwrap(); }
将handle.join()提前
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 循环
// 所以输出将不会交替出现,
handle.join().unwrap();
for i in 1..5 {
println!("hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1));
}
}
线程与 move 闭包
move 闭包,其经常与 thread::spawn 一起使用允许我们在一个线程中使用另一个线程的数据。
通过在闭包之前增加 move 关键字,强制闭包获取其使用的值的所有权
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(); }
闭包引用后,我们尝试drop v
use std::thread;
fn main() {
let v = vec![1, 2, 3];
let handle = thread::spawn(|| {
println!("Here's a vector: {:?}", v);
});
// 使用 move 关键字强制闭包获取其使用的值的所有权
// 保证主线程不会再使用 v
// 那么当在主线程中使用 v 时就会违反所有权规则
drop(v); // oh no!
handle.join().unwrap(); }
使用消息传递在线程间传送数据
Rust 中一个实现消息传递并发的主要工具是 通道(channel)
use std::thread;
use std::sync::mpsc;
fn main() {
// 发送端和接收端
// multi producer single comsumer
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
// send 方法返回一个Result<T, E> 类型,
// 所以如果接收端已经被丢弃了,将没有发送值的目标,
// 所以发送操作会返回错误
// 在这个例子中,出错的时候调用 unwrap 产生 panic
tx.send(val).unwrap();
// 方法会阻塞主线程执行直到从通道中接收一个值
// recv 和 try_recv 不会堵塞
let received = rx.recv().unwrap();
println!("Got: {}", received);
});
}
发送多个值
use std::thread;
use std::sync::mpsc;
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));
} });
for received in rx {
println!("Got: {}", received);
} }
通过clone创建多个生产者
# use std::thread;
# use std::sync::mpsc;
# use std::time::Duration; #
# fn main() {
// --snip--
let (tx, rx) = mpsc::channel();
let tx1 = mpsc::Sender::clone(&tx);
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--
#}
网友评论