use std::{sync::{mpsc, Arc, Mutex}, thread};
pub struct ThreadPool {
pub workers: Vec<Worker>,
pub sender: mpsc::Sender<Job>
}
impl ThreadPool {
pub fn new(pool_size: usize) -> ThreadPool {
assert!(pool_size > 0 && pool_size <= 100, "Pool size must be greater than 0 and less than or equal to 100");
let (sender, reciever) = mpsc::channel();
let reciever = Arc::new(Mutex::new(reciever));
let mut workers = Vec::with_capacity(pool_size);
for id in 0..pool_size {
workers.push(Worker::new(id, Arc::clone(&reciever)));
}
ThreadPool { workers, sender }
}
pub fn execute<F>(&self, f: F)
where
F: FnOnce() + Send + 'static
{
let job = Box::new(f);
match self.sender.send(job) {
Ok(_) => {}
Err(e) => {
println!("{}", e.to_string())
}
}
}
}
pub struct Worker {
pub id: usize,
pub thread: thread::JoinHandle<()>
}
type Job = Box<dyn FnOnce() + Send + 'static>;
impl Worker {
pub fn new(id: usize, reciever: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
let thread = thread::spawn(move ||
loop {
let job = reciever.lock().unwrap().recv().unwrap();
println!("Executing job with worker Id: {}", id);
job();
}
);
Worker { id, thread }
}
}