2 releases
new 0.1.1 | Nov 15, 2024 |
---|---|
0.1.0 | Nov 14, 2024 |
#526 in Concurrency
175 downloads per month
14KB
185 lines
lending thread pool
A thread pool where workers can lend their data to their tasks.
This library implements an admittedly simple thread pool with a peculiar feature: workers can hold on to some data and lend it to their tasks, thus greatly simplifying lifetimes in some scenarios, e.g. when you want to show the status of each thread (idle/running).
Usage
Here is a basic example:
use std::{thread::sleep, time::Duration};
use lending_thread_pool::ThreadPool;
let cores = 4;
let mut pool = ThreadPool::new(
(0..cores)
.map(|i| format!("Hello from worker {i}"))
.collect::<Vec<_>>(),
);
for _ in 0..cores {
pool.enqueue(move |worker_greetings| {
println!("Message from worker: {worker_greetings}");
sleep(Duration::from_millis(100));
});
}
As you might notice, ThreadPool::new
doesn't take a number, but rather a Vec
, which can contain anything.
The number of threads in the pool will correspond to the length of the provided Vec
.
Each item in the Vec
will be moved to the corresponding thread. This way, when a worker gets assigned a task,
it will be able to temporarily lend its data, through a mutable reference, to the task closure.
This lending mechanism makes it possible for tasks to share information. A common scenario where you might want to take advantage of this feature is showing some progress bars, for example, using indicatif we can do something like this:
use indicatif::{MultiProgress, ProgressBar};
use std::{thread::sleep, time::Duration};
use lending_thread_pool::ThreadPool;
// Assuming we have 4 cores
let cores = 4;
// Simulating 16 expensive things to do in parallel
let tasks = 16;
let multi_pb = MultiProgress::new();
let main_pb = multi_pb.add(ProgressBar::new(tasks));
// Initialize a thread pool where workers own their
// respective indicatif progress bars.
let mut pool = ThreadPool::new(
(0..cores)
.map(|_| multi_pb.add(ProgressBar::new(10)))
.collect::<Vec<_>>(),
);
for _ in 0..tasks {
// Simulate a long operation on the main thread
sleep(Duration::from_millis(100));
// We can now recycle the worker progress bar for each task
pool.enqueue(move |progress_bar| {
// Simulate a series of long operations on the worker thread
for _ in 0..10 {
sleep(Duration::from_millis(10));
progress_bar.inc(1);
}
progress_bar.reset();
});
main_pb.inc(1);
}
For complete examples, you can explore the project examples directory.
Dependencies
~7MB
~114K SLoC