lending_thread_pool

Crates.iolending_thread_pool
lib.rslending_thread_pool
version0.1.2
sourcesrc
created_at2024-11-14 17:23:19.010358
updated_at2024-11-19 07:58:56.815621
descriptionA thread pool where workers can lend their data to their tasks.
homepage
repositoryhttps://github.com/cdellacqua/lending_thread_pool.rs
max_upload_size
id1448121
size35,931
Carlo Dell'Acqua (cdellacqua)

documentation

README

lending thread pool

Documentation Crates.io Build status

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.

Commit count: 11

cargo fmt