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]

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));
    }
})

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));
}

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.

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]);
    }
}