2 use std::sync::{Arc, mpsc, Mutex};
4 type Job = Box<dyn FnOnce() + Send + 'static>;
13 thread: Option<thread::JoinHandle<()>>,
17 fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Message>>>) -> Worker {
18 let thread = Some(thread::spawn(move || loop {
19 let message = receiver.lock().unwrap().recv().unwrap();
22 Message::NewJob(job) => {
23 println!("Worker {} got a job, executing", id);
27 Message::Terminate => {
28 println!("Worker {} got terminated", id);
37 pub struct ThreadPool {
39 sender: mpsc::Sender<Message>,
43 /// Create a new thread pool.
48 pub fn new(size: usize) -> ThreadPool {
50 let mut workers = Vec::with_capacity(size);
52 let (sender, receiver) = mpsc::channel();
53 let receiver = Arc::new(Mutex::new(receiver));
56 workers.push(Worker::new(id, Arc::clone(&receiver)));
59 ThreadPool { workers, sender }
62 pub fn execute<F>(&self, f: F)
63 where F: FnOnce() + Send + 'static
65 self.sender.send(Message::NewJob(Box::new(f))).unwrap();
69 impl Drop for ThreadPool {
71 for _ in &self.workers {
72 self.sender.send(Message::Terminate).unwrap();
75 for worker in &mut self.workers {
76 println!("Shutting down worker {}", worker.id);
78 if let Some(thread) = worker.thread.take() {
79 thread.join().unwrap();