use std::sync::Arc; use std::sync::Mutex; use std::sync::mpsc; use std::thread; trait FnBox { fn call_box(self: Box); } impl FnBox for F { fn call_box(self: Box) { (*self)() } } type Job = Box; pub struct ThreadPool { workers: Vec, sender: mpsc::Sender, } impl ThreadPool { pub fn new(size: usize) -> Result { if size <= 0 { return Err("failed to create pool"); } 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))?); } Ok(ThreadPool { workers, sender, }) } pub fn spawn(f: F) -> thread::JoinHandle where F: FnOnce() -> T + Send + 'static, T: Send + 'static { thread::spawn(f) } pub fn execute(&self, f: F) where F: FnOnce() + Send + 'static { let job = Box::new(f); self.sender.send(job).unwrap(); } } struct Worker { id: usize, thread: thread::JoinHandle<()>, } impl Worker { pub fn new(id: usize, receiver: Arc>>) -> Result { let thread = thread::spawn(move || { loop { let job = receiver .lock().expect("lock poisoned!") .recv().unwrap(); println!("worker {} got job; executing...", id); job.call_box(); } }); Ok(Worker { id, thread, }) } }