pub trait ParThreadPool {
type ScopeRef<'s, 'env, 'scope>
where 'scope: 's,
'env: 'scope + 's;
// Required methods
fn run_in_scope<'s, 'env, 'scope, W>(
s: &Self::ScopeRef<'s, 'env, 'scope>,
work: W,
)
where W: Fn() + Send + 'scope + 'env,
'scope: 's,
'env: 'scope + 's;
fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
where for<'s> F: FnOnce(Self::ScopeRef<'s, 'env, 'scope>) + Send,
'env: 'scope;
fn max_num_threads(&self) -> NonZeroUsize;
}
Expand description
A thread pool that can be used for parallel computation.
orx_parallel abstracts away the thread pool implementation and can work with different thread pool implementations.
Parallel computation will not use any threads outside the pool. Default std thread pool assumes all OS threads are available in the pool.
§Examples
§Default std pool
requires std feature
Default parallel runner spawns scoped threads using std::thread::scope
.
use orx_parallel::*;
let sum = (0..1000).par().sum();
assert_eq!(sum, 1000 * 999 / 2);
// this is equivalent to
let sum = (0..1000).par().with_runner(DefaultRunner::default()).sum();
assert_eq!(sum, 1000 * 999 / 2);
§Rayon thread pool
requires rayon feature
The following example demonstrate using a rayon thread pool as the thread provider of the parallel computation.
use orx_parallel::*;
#[cfg(feature = "rayon-core")]
{
let pool = rayon::ThreadPoolBuilder::new()
.num_threads(4)
.build()
.unwrap();
// creating a runner for the computation
let runner = RunnerWithPool::from(&pool);
let sum = (0..1000).par().with_runner(runner).sum();
assert_eq!(sum, 1000 * 999 / 2);
// or reuse a runner multiple times (identical under the hood)
let mut runner = RunnerWithPool::from(&pool);
let sum = (0..1000).par().with_runner(&mut runner).sum();
assert_eq!(sum, 1000 * 999 / 2);
}
Note that since rayon::ThreadPool::scope only requires a shared reference &self
,
we can concurrently create as many runners as we want from the same thread pool and use them concurrently.
§Scoped thread pool
requires scoped_threadpool feature
The following example demonstrate using a scoped_threadpool thread pool as the thread provider of the parallel computation.
use orx_parallel::*;
#[cfg(feature = "scoped_threadpool")]
{
// creating a runner for the computation
let mut pool = scoped_threadpool::Pool::new(4);
let runner = RunnerWithPool::from(&mut pool);
let sum = (0..1000).par().with_runner(runner).sum();
assert_eq!(sum, 1000 * 999 / 2);
// or reuse a runner multiple times (identical under the hood)
let mut pool = scoped_threadpool::Pool::new(4);
let mut runner = RunnerWithPool::from(&mut pool);
let sum = (0..1000).par().with_runner(&mut runner).sum();
assert_eq!(sum, 1000 * 999 / 2);
}
Since scoped_thread_pool::Pool::scoped requires an exclusive reference &mut self
,
we can create one runner from a pool at a time, note use of &mut pool
in runner creation.
Required Associated Types§
Required Methods§
Sourcefn run_in_scope<'s, 'env, 'scope, W>(
s: &Self::ScopeRef<'s, 'env, 'scope>,
work: W,
)
fn run_in_scope<'s, 'env, 'scope, W>( s: &Self::ScopeRef<'s, 'env, 'scope>, work: W, )
Executes the work
within scope s
.
Sourcefn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
Executes the scoped computation f
.
Sourcefn max_num_threads(&self) -> NonZeroUsize
fn max_num_threads(&self) -> NonZeroUsize
Returns the maximum number of threads available in the pool.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.