1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
//! # `threadpool-simple` beta
//! Create threads and give them jobs very simply!
//!
//!
//! # Example
//!
//! ```
//! struct ThreadPool {
//! worker: Vec<Worker>,
//! sender: mpsc::Sender<Job>,
//! ```
//! Using channels for sending/receiving jobs between threads
//!
//!
use std::thread;
use std::sync::{Mutex, Arc, Condvar, MutexGuard, mpsc};
use std::time::Duration;
/// Alias for the type of a job, representing a closure or function that takes no arguments and does not return a value.
type Job = Box<dyn FnOnce() + Send + 'static>;
/// Struct representing a thread pool.
struct ThreadPool {
workers: Vec<Worker>,
sender: mpsc::Sender<Job>,
}
impl ThreadPool {
/// Creates a new thread pool with the specified size.
///
/// # Arguments
///
/// * `size` - The number of threads in the thread pool.
///
/// # Panics
///
/// Panics if the `size` is 0.
fn new(size: usize) -> Self {
assert!(size > 0);
let (sender, receiver) = mpsc::channel();
let receiver = Arc::new(Mutex::new(receiver));
let mut workers = Vec::with_capacity(size);
for id in 0..size {
workers.push(Worker::new(id, Arc::clone(&receiver)));
}
ThreadPool { workers, sender }
}
/// Executes a job in the thread pool.
///
/// # Arguments
///
/// * `f` - The closure or function representing the job to be executed.
///
/// # Example
///
/// ```
/// let pool = ThreadPool::new(4);
///
/// pool.execute(move || {
/// println!("Working on a job");
/// });
/// ```
fn execute<F>(&self, f: F)
where
F: FnOnce() + Send + 'static,
{
let job = Box::new(f);
self.sender.send(job).expect("Error while sending job in pool");
}
}
/// Struct representing a worker in the thread pool.
struct Worker {
id: usize,
thread: thread::JoinHandle<()>,
}
impl Worker {
/// Creates a new worker associated with the given ID and the receiver for job messages.
///
///! # Arguments
///!
///! * `id` - The ID of the worker.
///! * `receiver` - The receiver for job messages.
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
let thread = thread::spawn(move || loop {
let job = receiver.lock().unwrap().recv().unwrap();
println!("[THREAD{}] IS WORKING", id);
job();
});
Worker { id, thread }
}
}
/*
```
fn main() {
let pool = ThreadPool::new(100);
for i in 0..10 {
pool.execute(move || {
println!("Working on {i}");
});
}
thread::sleep(Duration::from_millis(1000));
}
```*/