jlizard-simple-threadpool

Crates.iojlizard-simple-threadpool
lib.rsjlizard-simple-threadpool
version0.3.0
created_at2025-12-05 13:59:28.023284+00
updated_at2025-12-09 20:44:31.385425+00
descriptionA simple, lightweight threadpool implementation
homepagehttps://gitlab.com/JurassicLizard/jlizard-simple-threadpool
repositoryhttps://gitlab.com/JurassicLizard/jlizard-simple-threadpool
max_upload_size
id1968264
size40,935
Salem B. (jurassicLizard)

documentation

https://docs.rs/jlizard-simple-threadpool

README

Simple threadpool

My own implementation of The Rust programming langauge official book implementation of a threadpool.

Features

  • Configurable pool size (single-threaded, multi-threaded, or auto-detect)
  • Queue limit with backpressure - prevents unbounded memory growth
  • Graceful shutdown with job completion guarantees
  • Worker signaling - jobs can signal all workers to stop via Arc<AtomicBool>

Usage

Basic Example

use jlizard_simple_threadpool::threadpool::ThreadPool;

// let pool = ThreadPool::new(4);  // 4 workers, or 0 for auto-detect, 1 for single-threaded
let pool = ThreadPool::default(); // runs the pool while auto detecting maximum threads

pool.execute(|| {
    println!("Job running in thread pool");
}).expect("Failed to execute");


Queue Limit with Backpressure

Prevent unbounded memory growth with configurable queue limits:

use jlizard_simple_threadpool::threadpool::ThreadPool;

// Default: 50,000 max jobs
let pool = ThreadPool::new(4);

// Custom limit using builder pattern
let pool = ThreadPool::new(4).max_jobs(100_000);

// When queue is full, execute() blocks with exponential backoff (1ms → 50ms)
for i in 0..1_000_000 {
    pool.execute(move || {
        // This won't cause unbounded memory growth
        println!("Job {}", i);
    }).expect("Failed to execute");
}

Worker Signaling (Early Termination)

For scenarios like hash collision detection where one worker should stop all others:

use jlizard_simple_threadpool::threadpool::ThreadPool;
use std::sync::{Arc, atomic::Ordering};

let pool = Arc::new(ThreadPool::default());

for i in 0..1000 {
    let pool_clone = Arc::clone(&pool);
    pool.execute(move || {
        // Simulate collision detection
        if i == 42 {
            pool_clone.signal_stop();  // Stop all workers
        }
    }).unwrap();
}

Or check the signal within jobs:

use jlizard_simple_threadpool::threadpool::ThreadPool;
use std::sync::atomic::Ordering;

let pool = ThreadPool::default();
let kill_signal = pool.get_kill_signal();
pool.execute(move || {
    for i in 0..1_000_000 {
        if kill_signal.load(Ordering::Relaxed) {
            return;  // Stop early
        }
        // Do work...
    }
}).unwrap();

API

  • new(size: u8) - Create pool (0=auto, 1=single-threaded, N=N workers)
  • max_jobs(limit: usize) - Set max queue size (builder pattern, default: 50,000)
  • execute<F>(&self, f: F) - Execute job (blocks with backpressure when queue is full)
  • signal_stop(&self) - Signal all workers to stop after current job
  • get_kill_signal(&self) - Get Arc<AtomicBool> to check/set from jobs
  • is_single_threaded(&self) - Check if single-threaded mode

Example Implementation

vex2pdf usage

License

The Unlicense

Commit count: 0

cargo fmt