Edit: aktualizowana Rust 1.x
dla obu tych zadań (zakończyć i zawiesić wątku) można wykorzystać kanały.
Oto jak wątek może zostać rozwiązana zewnętrznie:
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(());
}
Oznacza to, że na każdej iteracji pętli pracownika możemy sprawdzić, czy ktoś powiadomił nas poprzez kanał. Jeśli tak lub jeśli drugi koniec kanału wykracza poza zakres, po prostu przerywamy pętlę.
Oto jak nitki może być „zawieszony” i „wznowić”:
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(());
}
}
Tutaj używamy recv()
metodę, która zawiesza wątek aż coś przybywa na kanale, tak aby wznowić wątek ty wystarczy wysłać coś (wartość jednostki ()
w tym przypadku) przez kanał. Jeśli koniec transmisji kanału zostanie przerwany, recv()
zwróci Err(())
- używamy tego, aby opuścić pętlę.
Kanały to najprostszy i najbardziej naturalny (IMO) sposób wykonywania tych zadań, ale nie najskuteczniejszy. Istnieją inne prymitywy współbieżności, które można znaleźć w module std::sync
. Należą one do niższego poziomu niż kanały, ale mogą być bardziej wydajne w określonych zadaniach.