[][src]Struct workerpool::Pool

pub struct Pool<T> where
    T: Worker
{ /* fields omitted */ }

Abstraction of a thread pool for basic parallelism.

Methods

impl<T: Worker> Pool<T>[src]

pub fn new(num_threads: usize) -> Pool<T>[src]

Creates a new thread pool capable of executing num_threads number of jobs concurrently.

Panics

This function will panic if num_threads is 0.

Examples

Create a new thread pool capable of executing four jobs concurrently:

use workerpool::Pool;

let pool: Pool<MyWorker> = Pool::new(4);

pub fn with_name(name: String, num_threads: usize) -> Pool<T>[src]

Creates a new thread pool capable of executing num_threads number of jobs concurrently. Each thread will have the name name.

Panics

This function will panic if num_threads is 0.

Examples

use std::thread;
use workerpool::Pool;
use workerpool::thunk::{Thunk, ThunkWorker};

let pool: Pool<ThunkWorker<()>> = Pool::with_name("worker".into(), 2);
for _ in 0..2 {
    pool.execute(Thunk::of(|| {
        assert_eq!(
            thread::current().name(),
            Some("worker")
        );
    }));
}
pool.join();

pub fn execute(&self, inp: T::Input)[src]

Executes with the input on a worker in the pool. Non-blocking and disregards output of the worker's execution.

Examples

Execute four jobs on a thread pool that can run two jobs concurrently:

use workerpool::Pool;
use workerpool::thunk::{Thunk, ThunkWorker};

let pool: Pool<ThunkWorker<()>> = Pool::new(2);
pool.execute(Thunk::of(|| println!("hello")));
pool.execute(Thunk::of(|| println!("world")));
pool.execute(Thunk::of(|| println!("foo")));
pool.execute(Thunk::of(|| println!("bar")));
pool.join();

pub fn execute_to(&self, tx: Sender<T::Output>, inp: T::Input)[src]

Executes with the input on a worker in the pool. Non-blocking and sends output of the worker's execution to the given sender. If you want to use crossbeam_channel::Sender instead of std::sync::mpsc::Sender, enable the crossbeam feature for this library.

Examples

Execute four jobs on a thread pool that can run two jobs concurrently:

use std::sync::mpsc::channel;
use workerpool::Pool;
use workerpool::thunk::{Thunk, ThunkWorker};

let pool: Pool<ThunkWorker<i32>> = Pool::new(2);
let (tx, rx) = channel();
pool.execute_to(tx.clone(), Thunk::of(|| 1));
pool.execute_to(tx.clone(), Thunk::of(|| 2));
pool.execute_to(tx.clone(), Thunk::of(|| 3));
pool.execute_to(tx.clone(), Thunk::of(|| 4));
assert_eq!(10, rx.iter().take(4).sum());

pub fn queued_count(&self) -> usize[src]

Returns the number of jobs waiting to executed in the pool.

Examples

use workerpool::Pool;
use workerpool::thunk::{Thunk, ThunkWorker};
use std::time::Duration;
use std::thread::sleep;

let pool: Pool<ThunkWorker<()>> = Pool::new(2);
for _ in 0..10 {
    pool.execute(Thunk::of(|| {
        sleep(Duration::from_secs(100));
    }));
}

sleep(Duration::from_secs(1)); // wait for threads to start
assert_eq!(8, pool.queued_count());

pub fn active_count(&self) -> usize[src]

Returns the number of currently active threads.

Examples

use workerpool::Pool;
use workerpool::thunk::{Thunk, ThunkWorker};
use std::time::Duration;
use std::thread::sleep;

let pool = Pool::<ThunkWorker<()>>::new(4);
for _ in 0..10 {
    pool.execute(Thunk::of(|| {
        sleep(Duration::from_secs(100));
    }))
}

sleep(Duration::from_secs(1)); // wait for threads to start
assert_eq!(4, pool.active_count());

pub fn max_count(&self) -> usize[src]

Returns the maximum number of threads the pool will execute concurrently.

Examples

use workerpool::Pool;

let mut pool: Pool<MyWorker> = Pool::new(4);
assert_eq!(4, pool.max_count());

pool.set_num_threads(8);
assert_eq!(8, pool.max_count());

pub fn panic_count(&self) -> usize[src]

Returns the number of panicked threads over the lifetime of the pool.

Examples

use workerpool::Pool;
use workerpool::thunk::{Thunk, ThunkWorker};

let pool: Pool<ThunkWorker<()>> = Pool::new(4);
for n in 0..10 {
    pool.execute(Thunk::of(move || {
        // simulate a panic
        if n % 2 == 0 {
            panic!()
        }
    }));
}
pool.join();

assert_eq!(5, pool.panic_count());

pub fn set_num_threads(&mut self, num_threads: usize)[src]

Sets the number of worker-threads to use as num_threads. Can be used to change the workerpool size during runtime. Will not abort already running or waiting threads.

Panics

This function will panic if num_threads is 0.

Examples

use workerpool::Pool;
use workerpool::thunk::{Thunk, ThunkWorker};
use std::time::Duration;
use std::thread::sleep;

let mut pool: Pool<ThunkWorker<()>> = Pool::new(4);
for _ in 0..10 {
    pool.execute(Thunk::of(|| {
        sleep(Duration::from_secs(100));
    }));
}

sleep(Duration::from_secs(1)); // wait for threads to start
assert_eq!(4, pool.active_count());
assert_eq!(6, pool.queued_count());

// Increase thread capacity of the pool
pool.set_num_threads(8);

sleep(Duration::from_secs(1)); // wait for new threads to start
assert_eq!(8, pool.active_count());
assert_eq!(2, pool.queued_count());

// Decrease thread capacity of the pool
// No active threads are killed
pool.set_num_threads(4);

assert_eq!(8, pool.active_count());
assert_eq!(2, pool.queued_count());

pub fn join(&self)[src]

Block the current thread until all jobs in the pool have been executed.

Calling join on an empty pool will cause an immediate return. join may be called from multiple threads concurrently. A join is an atomic point in time. All threads joining before the join event will exit together even if the pool is processing new jobs by the time they get scheduled.

Calling join from a thread within the pool will cause a deadlock. This behavior is considered safe.

Examples

use workerpool::Pool;
use workerpool::thunk::{Thunk, ThunkWorker};
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};

let pool: Pool<ThunkWorker<()>> = Pool::new(8);
let test_count = Arc::new(AtomicUsize::new(0));

for _ in 0..42 {
    let test_count = test_count.clone();
    pool.execute(Thunk::of(move || {
        test_count.fetch_add(1, Ordering::Relaxed);
    }))
}

pool.join();
assert_eq!(42, test_count.load(Ordering::Relaxed));

Trait Implementations

impl<T: Worker> Default for Pool<T>[src]

Create a thread pool with one thread per CPU. On machines with hyperthreading, this will create one thread per hyperthread.

impl<T: Worker> Clone for Pool<T>[src]

fn clone(&self) -> Pool<T>[src]

Cloning a pool will create a new handle to the pool. The behavior is similar to Arc.

We could for example submit jobs from multiple threads concurrently.

use workerpool::Pool;
use workerpool::thunk::{Thunk, ThunkWorker};
use std::thread;
use std::sync::mpsc::channel;

let pool: Pool<ThunkWorker<()>> = Pool::with_name("clone example".into(), 2);

let results = (0..2)
    .map(|i| {
        let pool = pool.clone();
        thread::spawn(move || {
            let (tx, rx) = channel();
            for i in 1..12 {
                let tx = tx.clone();
                pool.execute(Thunk::of(move || {
                    tx.send(i).expect("channel will be waiting");
                }));
            }
            drop(tx);
            if i == 0 {
                rx.iter().fold(0, |accumulator, element| accumulator + element)
            } else {
                rx.iter().fold(1, |accumulator, element| accumulator * element)
            }
        })
    })
    .map(|join_handle| join_handle.join().expect("collect results from threads"))
    .collect::<Vec<usize>>();

assert_eq!(vec![66, 39916800], results);

fn clone_from(&mut self, source: &Self)
1.0.0
[src]

Performs copy-assignment from source. Read more

impl<T: Worker> Eq for Pool<T>[src]

impl<T: Worker> PartialEq<Pool<T>> for Pool<T>[src]

fn eq(&self, other: &Pool<T>) -> bool[src]

Check if you are working with the same pool

use workerpool::Pool;

let a: Pool<MyWorker> = Pool::new(2);
let b: Pool<MyWorker> = Pool::new(2);

assert_eq!(a, a);
assert_eq!(b, b);

assert_ne!(a, b);
assert_ne!(b, a);

#[must_use]
fn ne(&self, other: &Rhs) -> bool
1.0.0
[src]

This method tests for !=.

impl<T: Worker> Debug for Pool<T>[src]

Auto Trait Implementations

impl<T> Send for Pool<T> where
    <T as Worker>::Input: Send,
    <T as Worker>::Output: Send

impl<T> Sync for Pool<T> where
    <T as Worker>::Input: Send,
    <T as Worker>::Output: Send

Blanket Implementations

impl<T> From for T[src]

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = !

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Erased for T