pub struct SharedThread<T> { /* private fields */ }Expand description
A wrapper around std::thread::JoinHandle that allows for multiple waiters.
The high-level differences between SharedThread and JoinHandle are:
jointakes&selfrather than&mut self.joinreturns&Trather thanT. For taking ownership ofT, seeinto_output.SharedThreadprovidestry_join.- Rather than converting panics in into
std::thread::Result, which usually requires the caller to.unwrap()every.join(),SharedThreadpropagates panics automatically.
§Example
use shared_thread::SharedThread;
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
// Use this flag to tell our shared thread when to stop.
static EXIT_FLAG: AtomicBool = AtomicBool::new(false);
// Start a background thread that we'll share with several waiting threads.
let shared_thread = SharedThread::spawn(|| {
// Pretend this is some expensive, useful background work...
while (!EXIT_FLAG.load(Relaxed)) {}
42
});
// How to share a SharedThread object with other threads is up to you. In this sense it's like
// any other object you might need to share, like say a HashMap or a File. The common options
// are to put it in an Arc, or to let "scoped" threads borrow it directly. Let's use scoped
// threads.
std::thread::scope(|scope| {
// Spawn three waiter threads that each wait on the shared thread.
let waiter1 = scope.spawn(|| shared_thread.join());
let waiter2 = scope.spawn(|| shared_thread.join());
let waiter3 = scope.spawn(|| shared_thread.join());
// In this example, the shared thread is going to keep looping until we set the EXIT_FLAG.
// In the meantime, .is_finished() returns false, and .try_join() returns None.
assert!(!shared_thread.is_finished());
assert_eq!(shared_thread.try_join(), None);
// Ask the shared thread to stop looping.
EXIT_FLAG.store(true, Relaxed);
// At this point the calls to .join() above will return quickly, and each of the waiter
// threads will get a reference to the shared thread's output, &42.
assert_eq!(*waiter1.join().unwrap(), 42);
assert_eq!(*waiter2.join().unwrap(), 42);
assert_eq!(*waiter3.join().unwrap(), 42);
// Now that the shared thread has finished, .is_finished() returns true, and .try_join()
// returns Some(&42).
assert!(shared_thread.is_finished());
assert_eq!(*shared_thread.try_join().unwrap(), 42);
});
// We can take ownership of the output by consuming the SharedThread object. As with any
// non-Copy type in Rust, this requires that the SharedThread is not borrowed.
assert_eq!(shared_thread.into_output(), 42);Implementations§
Sourcepub fn new(handle: JoinHandle<T>) -> Self
pub fn new(handle: JoinHandle<T>) -> Self
Wrap an existing
JoinHandle.
This is equivalent to SharedThread::from.
Sourcepub fn try_join(&self) -> Option<&T>
pub fn try_join(&self) -> Option<&T>
Return Some(&T) if the shared thread has already finished, otherwise None. This never
blocks.
§Panics
This function panics if the shared thread panicked.
Sourcepub fn join(&self) -> &T
pub fn join(&self) -> &T
Wait for the shared thread to finish, then return &T. This blocks the current thread
until the shared thread is finished.
§Panics
This function panics if the shared thread panicked.
Sourcepub fn into_output(self) -> T
pub fn into_output(self) -> T
Wait for the shared thread to finish, then return T. This blocks the current thread until
the shared thread is finished. This requires ownership of the SharedThread and consumes
it.
§Panics
This function panics if the shared thread panicked.
Sourcepub fn is_finished(&self) -> bool
pub fn is_finished(&self) -> bool
Return true if the shared thread has finished, false otherwise.
This function never blocks. If it returns true, try_join is
guaranteed to return Some(T), and join is guaranteed to return
quickly.
§Panics
This function may panic if the shared thread panicked. Currently it only panics if another method has already panicked, but this is not guaranteed.