Struct jobsteal::Spawner
[−]
[src]
pub struct Spawner<'pool, 'scope> { /* fields omitted */ }
A job spawner associated with a specific scope.
Jobs spawned using this must outlive the scope.
The scope
function can be used to create a more focused spawner.
Methods
impl<'pool, 'scope> Spawner<'pool, 'scope>
[src]
fn recurse<F>(&self, f: F) where
F: 'scope + Send + FnOnce(&Spawner<'pool, 'scope>),
F: 'scope + Send + FnOnce(&Spawner<'pool, 'scope>),
Submit a job to be executed by the thread pool and given access to the thread pool.
The job's contents must outlive the spawner's scope. If they don't,
you can create a more focused scope by calling the scope
function on the spawner,
and then submitting the job.
Jobs are passed a handle to the spawner, so work can be split recursively.
Examples
Basic usage:
use jobsteal::make_pool; let mut pool = make_pool(2).unwrap(); // get a handle to the pool's spawner. let spawner = pool.spawner(); // execute a job which can spawn other jobs. spawner.recurse(|inner| { for i in 0..10 { inner.submit(move || println!("{}", i)); } })
fn submit<F>(&self, f: F) where
F: 'scope + Send + FnOnce(),
F: 'scope + Send + FnOnce(),
Submit a job to be executed by the thread pool.
The job's contents must outlive the spawner's scope. If they don't,
you can create a more focused scope by calling the scope
function on the spawner,
and then submitting the job.
Jobs are passed a handle to the spawner, so work can be split recursively.
Examples
Basic usage:
use jobsteal::make_pool; let mut pool = make_pool(2).unwrap(); // get a handle to the pool's spawner. let spawner = pool.spawner(); for i in 0..10 { // this spawner can only be used to execute jobs which fully own their data. spawner.submit(move || println!("Hello {}", i)); }
fn scope<'new, F, R>(&'new self, f: F) -> R where
'scope: 'new,
F: 'new + FnOnce(&Spawner<'pool, 'new>) -> R,
R: 'new,
'scope: 'new,
F: 'new + FnOnce(&Spawner<'pool, 'new>) -> R,
R: 'new,
Construct a new spawning scope smaller than the one this spawner resides in.
Examples
Incrementing all the values in a vector.
use jobsteal::make_pool; let mut pool = make_pool(2).unwrap(); let spawner = pool.spawner(); let mut v = (0..1024).collect::<Vec<_>>(); spawner.scope(|scope| { // within this scope, we can spawn jobs that access data outside of it. for i in &mut v { scope.submit(move || *i *= 2); } }); // all jobs submitted in the scope are completed before execution resumes here.
fn join<A, B, R_A, R_B>(&self, oper_a: A, oper_b: B) -> (R_A, R_B) where
A: Send + for<'new> FnOnce(&Spawner<'pool, 'new>) -> R_A,
B: Send + for<'new> FnOnce(&Spawner<'pool, 'new>) -> R_B,
R_A: Send,
R_B: Send,
A: Send + for<'new> FnOnce(&Spawner<'pool, 'new>) -> R_A,
B: Send + for<'new> FnOnce(&Spawner<'pool, 'new>) -> R_B,
R_A: Send,
R_B: Send,
Execute two closures, possibly asynchronously, and return their results. This will block until they are both complete.
Examples
Sorting a list in parallel.
extern crate jobsteal; use jobsteal::Spawner; fn main() { // a simple quicksort fn quicksort<T: Ord + Send>(data: &mut [T], spawner: &Spawner) { if data.len() <= 1 { return; } // partition the data. let pivot = partition(data); let (a, b) = data.split_at_mut(pivot); // recursively sort the two parts using the threadpool. spawner.join( |inner| quicksort(a, inner), |inner| quicksort(b, inner), ); } // partition the array such that all elements on the left of the partition // are less than those to the right. fn partition<T: Ord>(data: &mut [T]) -> usize { let pivot = data.len() - 1; let mut i = 0; for j in 0..pivot { if data[j] <= data[pivot] { data.swap(i, j); i += 1; } } data.swap(i, pivot); i } let len = 1024; let mut to_sort = (0..len).rev().collect::<Vec<_>>(); let mut pool = jobsteal::make_pool(0).unwrap(); quicksort(&mut to_sort, &pool.spawner()); for pair in to_sort.windows(2) { assert!(pair[1] >= pair[0]); } }