pub struct WorkQueue<T: Send + 'static> { /* private fields */ }Expand description
A work-stealing work queue for distributing tasks across multiple workers.
WorkQueue<T> is Clone — all clones share the same underlying state,
so tasks pushed from one clone are visible to all others.
§Thread safety
WorkQueue<T> is Send + Sync when T: Send. Multiple threads may
call push and steal
concurrently without external synchronisation.
§Examples
use oximedia_core::work_queue_ws::WorkQueue;
use std::thread;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
let wq = WorkQueue::<u32>::new(4);
for i in 0..100_u32 {
wq.push(i);
}
let total = Arc::new(AtomicUsize::new(0));
let mut handles = Vec::new();
for _ in 0..4 {
let wq2 = wq.clone();
let count = Arc::clone(&total);
handles.push(thread::spawn(move || {
while let Some(_task) = wq2.steal() {
count.fetch_add(1, Ordering::Relaxed);
}
}));
}
for h in handles { h.join().expect("thread panicked"); }
assert_eq!(total.load(Ordering::Relaxed), 100);Implementations§
Source§impl<T: Send + 'static> WorkQueue<T>
impl<T: Send + 'static> WorkQueue<T>
Sourcepub fn new(workers: usize) -> Self
pub fn new(workers: usize) -> Self
Creates a new WorkQueue with workers local deques.
workers controls the number of distinct steal handles. A value of
0 is clamped to 1.
§Examples
use oximedia_core::work_queue_ws::WorkQueue;
let wq = WorkQueue::<i32>::new(4);
assert_eq!(wq.len(), 0);Sourcepub fn push(&self, task: T)
pub fn push(&self, task: T)
Pushes a task into the global injection queue.
§Examples
use oximedia_core::work_queue_ws::WorkQueue;
let wq = WorkQueue::<u32>::new(2);
wq.push(42_u32);
assert_eq!(wq.len(), 1);Sourcepub fn steal(&self) -> Option<T>
pub fn steal(&self) -> Option<T>
Attempts to steal a task from any available source.
The implementation first drains the global injector into a local worker deque (slot 0), then tries to pop from each worker in round-robin order, retrying on contention.
Returns None when all queues appear empty.
§Examples
use oximedia_core::work_queue_ws::WorkQueue;
let wq = WorkQueue::<u32>::new(2);
wq.push(1_u32);
wq.push(2_u32);
let t1 = wq.steal();
let t2 = wq.steal();
assert!(t1.is_some());
assert!(t2.is_some());Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the approximate number of tasks currently in the queue.
This value may be slightly stale due to concurrent operations. It saturates at zero rather than going negative.
§Examples
use oximedia_core::work_queue_ws::WorkQueue;
let wq = WorkQueue::<u32>::new(2);
wq.push(1_u32);
wq.push(2_u32);
assert_eq!(wq.len(), 2);