Edit: Updated for Rust 1.x
For both of these tasks (ending and pausing a thread) you can use channels.
This is how a thread can be terminated externally:
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(()); }
That is, at each iteration of the work cycle, we check whether someone notified us via the channel. If so, or if the other end of the channel is out of scope, we just break the loop.
Here's how a thread can be โpausedโ and โresumedโ:
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(()); } }
Here we use the recv() method, which pauses the stream until something appears on the channel, so to resume the stream, you just need to send something (unit value () in this case) through the channel. If the transmitting end of the channel is omitted, recv() will return Err(()) - we use it to exit the loop.
Channels are the easiest and most natural way (IMO) to complete these tasks, but not the most effective. There are other concurrency primitives that you can find in the std::sync module. They are at a lower level than channels, but can be more effective in specific tasks.
Vladimir Matveev
source share