Edit: für Rust 1.x aktualisiert
Für beide Aufgaben (beenden und einen Thread Suspend) Sie können Kanäle verwenden.
Hier ist, wie ein Faden von außen beendet werden konnte:
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(());
}
Das heißt, bei jeder Iteration eines Arbeitnehmers Schleife überprüfen wir, ob uns jemand durch einen Kanal informiert. Wenn ja oder wenn das andere Ende des Kanals den Rahmen verlassen hat, brechen wir einfach die Schleife.
Hier ist, wie ein Thread könnte „suspendiert“ und „Wiederaufnahme“:
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(());
}
}
Hier verwenden wir recv()
Methode, die den Faden aussetzt, bis etwas auf dem Kanal ankommt, so um den Faden wieder aufnehmen Sie muss nur etwas (Einheitswert ()
in diesem Fall) durch den Kanal senden. Wenn das sendende Ende des Kanals gelöscht wird, gibt recv()
Err(())
zurück - wir benutzen dies, um die Schleife zu verlassen.
Kanäle sind die einfachste und natürlichste (IMO) Art, diese Aufgaben zu erledigen, aber nicht die effizienteste. Es gibt andere Concurrency-Primitive, die Sie im std::sync
Modul finden können. Sie gehören zu einer niedrigeren Ebene als Kanäle, können aber in bestimmten Aufgaben effizienter sein.