編輯:更新的鏽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
模塊中找到。它們屬於比渠道低的層次,但在特定任務中可以更有效率。