| use std::thread; | use std::thread; | ||||
| use std::sync::{mpsc, Mutex, Arc}; | |||||
| pub struct ThreadPool{ | pub struct ThreadPool{ | ||||
| workers: Vec<Worker>, | workers: Vec<Worker>, | ||||
| sender: mpsc::Sender<Job>, | |||||
| } | } | ||||
| type Job = Box<dyn FnOnce() + Send + 'static>; | |||||
| impl ThreadPool { | impl ThreadPool { | ||||
| pub fn new(size: usize) -> ThreadPool { | pub fn new(size: usize) -> ThreadPool { | ||||
| assert!(size > 0); | assert!(size > 0); | ||||
| let (sender, receiver) = mpsc::channel(); | |||||
| let receiver = Arc::new(Mutex::new(receiver)); | |||||
| let mut workers = Vec::with_capacity(size); | let mut workers = Vec::with_capacity(size); | ||||
| for id in 0..size { | for id in 0..size { | ||||
| workers.push(Worker::new(id)); | |||||
| workers.push(Worker::new(id, Arc::clone(&receiver))); | |||||
| } | } | ||||
| ThreadPool { | ThreadPool { | ||||
| workers | |||||
| workers, | |||||
| sender, | |||||
| } | } | ||||
| } | } | ||||
| pub fn execute<F>(&self, f: F) | pub fn execute<F>(&self, f: F) | ||||
| where F: FnOnce() + Send + 'static { | |||||
| where F: FnOnce() + Send + 'static | |||||
| { | |||||
| let job = Box::new(f); | |||||
| self.sender.send(job).unwrap(); | |||||
| } | } | ||||
| // pub fn spawn<F, T>(f: F) -> JoinHandle<T> | // pub fn spawn<F, T>(f: F) -> JoinHandle<T> | ||||
| } | } | ||||
| impl Worker { | impl Worker { | ||||
| fn new(id: usize) -> Worker { | |||||
| let thread = thread::spawn(|| {}); | |||||
| 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!("Worker {} got a job, executing.", id); | |||||
| job(); | |||||
| } | |||||
| }); | |||||
| Worker { | Worker { | ||||
| id, | id, |