Reputation: 213
The Rust crate crossbeam-deque
has a nice example function in its documentation:
use crossbeam_deque::{Injector, Stealer, Worker};
use std::iter;
fn find_task<T>(
local: &Worker<T>,
global: &Injector<T>,
stealers: &[Stealer<T>],
) -> Option<T> {
// Pop a task from the local queue, if not empty.
local.pop().or_else(|| {
// Otherwise, we need to look for a task elsewhere.
iter::repeat_with(|| {
// Try stealing a batch of tasks from the global queue.
global.steal_batch_and_pop(local)
// Or try stealing a task from one of the other threads.
.or_else(|| stealers.iter().map(|s| s.steal()).collect())
})
// Loop while no task was stolen and any steal operation needs to be retried.
.find(|s| !s.is_retry())
// Extract the stolen task, if there is one.
.and_then(|s| s.success())
})
}
How can this function be used in a threaded Rust program?
While trying I ran into issues with borrowing, lifetimes and scopes.
At least there should be a global queue:
let global_queue = Injector::new();
global_queue.push(42);
global_queue.push(69);
global_queue.push(1337);
and perhaps a vector of stealers:
let mut stealers: Vec<Stealer<i32>> = vec![];
and for each thread we should do something like
let local_queue = Worker::new_fifo();
stealers.push(local_queue.stealer());
and then each thread should find a task like
let task = find_task(&local_queue, &global_queue, &stealers);
but I haven't managed to put these together in a threaded program (calling find_task
in a thread) that actually compiles.
Upvotes: 0
Views: 26