1use std::thread;
7use std::sync::mpsc;
8use std::sync::Arc;
9use std::sync::Mutex;
10
11enum Message {
12 NewJob(Job),
13 Terminate,
14}
15
16pub struct ThreadPool
17{
18 workers: Vec<Worker>,
19 sender:mpsc::Sender<Message>,
20}
21
22
23trait FnBox {
26 fn call_box(self:Box<Self>);
27}
28
29impl<F:FnOnce()> FnBox for F{
30 fn call_box(self:Box<F>){
31 (*self)()
32 }
33}
34
35type Job = Box<dyn FnBox+ Send+ 'static>;
36
37impl ThreadPool {
38 pub fn new(size:usize)->ThreadPool{
44 assert!(size>0);
45 let mut workers = Vec::with_capacity(size);
46
47 let (sender,receiver) = mpsc::channel();
48 let receiver = Arc::new(Mutex::new(receiver));
49
50 for id in 0..size{
51 workers.push(Worker::new(id,Arc::clone(&receiver)));
52 }
53 ThreadPool { workers,sender }
54 }
55
56 pub fn execute<F>(&self,f:F)
57 where
58 F:FnOnce() + Send + 'static
59 {
60 let job = Box::new(f);
61 self.sender.send(Message::NewJob(job)).unwrap();
62
63 }
64}
65
66struct Worker {
67 id: usize,
68 thread: Option<thread::JoinHandle<()>>,
69}
70
71impl Worker {
72 fn new(id: usize,receiver:Arc<Mutex<mpsc::Receiver<Message>>>)->Worker{
73
74 let thread = thread::spawn(move|| loop{
75 let message = receiver.lock().unwrap().recv().unwrap();
76 match message {
77 Message::NewJob(job) => {
78 job.call_box();
79 },
80 Message::Terminate => {
81 println!("worker {} was told to terminate.",id);
82 break;
83 }
84 }
85
86 });
87
88 Worker{id,thread:Some(thread)}
89 }
90}
91
92impl Drop for ThreadPool {
93 fn drop(&mut self) {
94 for _ in &mut self.workers {
95 self.sender.send(Message::Terminate).unwrap();
96 }
97
98 for worker in &mut self.workers {
99
100 if let Some(thread) = worker.thread.take(){
101 thread.join().unwrap();
102 };
103 }
104 }
105}