pub struct WorkQueue<T: Send> { /* private fields */ }
Expand description
A generic work queue for any work element that is Send. This queue is symmetric, in that any thread with a copy of it can add work or remove work.
§Examples
The general usage pattern is to create a queue in a controller/main thread and clone it into other threads.
use workctl::WorkQueue;
use std::thread;
// Create a WorkQueue to share work into other threads.
let mut wq = WorkQueue::new();
// Make a clone of the queue (this is like Arc, it's creating another
// reference to the actual underlying queue).
// This gets moved into the spawned thread.
let mut thread_wq = wq.clone();
let handle = thread::spawn(move || {
loop {
if let Some(work) = thread_wq.pull_work() {
// Do some work!
println!("Got work {} in spawned thread.", work);
break;
} else {
thread::yield_now();
}
}
});
wq.push_work(1337);
handle.join().unwrap();
§Panics
The functions on this type will panic if the underlying mutex became poisoned; that is, if there was a panic during the execution of any mutex-acquiring function. This is pretty unlikely.
Implementations§
Source§impl<T: Send> WorkQueue<T>
impl<T: Send> WorkQueue<T>
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a new, empty WorkQueue with at least the given capacity.
Sourcepub fn pull_work(&mut self) -> Option<T>
pub fn pull_work(&mut self) -> Option<T>
Blocks the current thread until it can check if work is available, then acquires the work data and removes it from the queue.
Returns None
if there is currently no work in the queue.
Sourcepub fn push_work(&mut self, work_element: T) -> usize
pub fn push_work(&mut self, work_element: T) -> usize
Blocks the current thread until it can add work to the queue, adding that work at the end of the queue.
Returns the number of elements in the queue after inserting that work.
Sourcepub fn wait(&mut self, run_flag: &SyncFlagRx) -> Option<T>
pub fn wait(&mut self, run_flag: &SyncFlagRx) -> Option<T>
Blocks the current thread until either some work is available or run_flag
becomes false.
Returns either a piece of work or None, signifying that no more work is
expected because run_flag
is false.
§Examples
Based on the example for the type, above, we can create a worker that looks for jobs until it’s told to stop.
use workctl::{WorkQueue, new_syncflag};
use std::thread;
let mut wq = WorkQueue::new();
let (mut run_tx, run_rx) = new_syncflag(true);
let mut thread_wq = wq.clone();
let handle = thread::spawn(move || {
let mut work_done = 0;
// Wait until either there is work or the worker should quit
while let Some(work) = thread_wq.wait(&run_rx) {
// Do some work!
println!("Got work {} in spawned thread.", work);
work_done += 1;
}
assert_eq!(work_done, 2,
"Expected worker to do 2 work; it did {}.", work_done);
});
// Put some work in the queue.
wq.push_work(1337);
wq.push_work(1024);
// Wait a bit.
thread::sleep_ms(1000);
// Tell the worker to stop looking for work
run_tx.set(false);
// This work won't get done.
wq.push_work(1776);
handle.join().unwrap();