Struct SingleQueueThreadpool

Source
pub struct SingleQueueThreadpool { /* private fields */ }
Expand description

Abstraction of a thread pool for basic parallelism.

Implementations§

Source§

impl SingleQueueThreadpool

Source

pub fn execute<F>(&self, job: F)
where F: FnOnce() + Send + 'static,

Executes the function job on a thread in the pool.

§Examples

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

let pool = lft_rust::single_queue_threadpool_auto_config();
pool.execute(|| println!("hello"));
pool.execute(|| println!("world"));
pool.execute(|| println!("foo"));
pool.execute(|| println!("bar"));
pool.join();
Source

pub fn queued_count(&self) -> usize

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

§Examples
use lft_rust::SingleQueueThreadpool;
use std::time::Duration;
use std::thread::sleep;

let pool = lft_rust::single_queue_threadpool_builder()
                        .num_workers(2)
                        .build();
for _ in 0..10 {
    pool.execute(|| {
        sleep(Duration::from_secs(100));
    });
}

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

pub fn active_count(&self) -> usize

Returns the number of currently active worker threads.

§Examples
use std::time::Duration;
use std::thread::sleep;

let pool = lft_rust::single_queue_threadpool_builder()
                        .num_workers(4)
                        .build();

for _ in 0..10 {
    pool.execute(move || {
        sleep(Duration::from_secs(100));
    });
}

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

pub fn max_count(&self) -> usize

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

§Examples
let pool = lft_rust::single_queue_threadpool_builder()
                        .num_workers(4)
                        .build();
assert_eq!(4, pool.max_count());

pool.set_num_workers(8);
assert_eq!(8, pool.max_count());
Source

pub fn panic_count(&self) -> usize

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

§Examples
let pool = lft_rust::single_queue_threadpool_auto_config();
for n in 0..10 {
    pool.execute(move || {
        // simulate a panic
        if n % 2 == 0 {
            panic!()
        }
    });
}
pool.join();

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

pub fn set_num_workers(&self, num_workers: usize)

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

§Panics

This function will panic if num_workers is 0.

§Examples
use std::time::Duration;
use std::thread::sleep;

let pool = lft_rust::single_queue_threadpool_builder()
                            .num_workers(4)
                            .build();

for _ in 0..10 {
    pool.execute(move || {
        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_workers(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_workers(4);

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

pub fn join(&self)

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.

Note: Join will not stop the worker threads. You will need to drop all instances of SingleQueueThreadpool for the worker threads to terminate.

§Examples
use lft_rust::SingleQueueThreadpool;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};

let pool = lft_rust::single_queue_threadpool_auto_config();
let test_count = Arc::new(AtomicUsize::new(0));

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

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

Trait Implementations§

Source§

impl Clone for SingleQueueThreadpool

Source§

fn clone(&self) -> SingleQueueThreadpool

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 std::thread;
use crossbeam_channel::unbounded;

let pool = lft_rust::single_queue_threadpool_builder()
                .worker_name("clone example")
                .num_workers(2)
                .build();

let results = (0..2)
    .map(|i| {
        let pool = pool.clone();
        thread::spawn(move || {
            let (tx, rx) = unbounded();
            for i in 1..12 {
                let tx = tx.clone();
                pool.execute(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);
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SingleQueueThreadpool

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for SingleQueueThreadpool

Source§

fn eq(&self, other: &SingleQueueThreadpool) -> bool

Check if you are working with the same pool

let a = lft_rust::single_queue_threadpool_auto_config();
let b = lft_rust::single_queue_threadpool_auto_config();

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

assert_ne!(a, b);
assert_ne!(b, a);
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for SingleQueueThreadpool

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.