编辑:更新的锈1.x的
对于这两个任务(终止和暂停线程),你可以使用信道。
下面是一个线程可以在外部终止:
use std::thread;
use std::time::Duration;
use std::sync::mpsc::{self, TryRecvError};
use std::io::{self, BufRead};
fn main() {
println!("Press enter to terminate the child thread");
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
loop {
println!("Working...");
thread::sleep(Duration::from_millis(500));
match rx.try_recv() {
Ok(_) | Err(TryRecvError::Disconnected) => {
println!("Terminating.");
break;
}
Err(TryRecvError::Empty) => {}
}
}
});
let mut line = String::new();
let stdin = io::stdin();
let _ = stdin.lock().read_line(&mut line);
let _ = tx.send(());
}
也就是说,一名工人循环的每个迭代,我们检查,如果有人通知我们通过一个通道。如果是,或者如果频道的另一端已经超出范围,我们只是打破循环。
下面是一个线程可以“暂停”和“恢复”:
use std::time::Duration;
use std::thread;
use std::sync::mpsc;
use std::io::{self, BufRead};
fn main() {
println!("Press enter to wake up the child thread");
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
loop {
println!("Suspending...");
match rx.recv() {
Ok(_) => {
println!("Working...");
thread::sleep(Duration::from_millis(500));
}
Err(_) => {
println!("Terminating.");
break;
}
}
}
});
let mut line = String::new();
let stdin = io::stdin();
for _ in 0..4 {
let _ = stdin.lock().read_line(&mut line);
let _ = tx.send(());
}
}
这里我们使用recv()
方法,挂起线程,直到东西到达通道上,所以为了恢复该线程你只需要通过该通道发送一些东西(在这种情况下为单元值()
)。如果通道的发送端被丢弃,recv()
将返回Err(())
- 我们用它来退出循环。
渠道是最容易和最自然(IMO)的方式来做这些任务,但不是最有效的。还有其他并发原语可以在std::sync
模块中找到。它们属于比渠道低的层次,但在特定任务中可以更有效率。