1use std::thread;
10use std::sync::mpsc;
11use std::sync::Arc;
12use std::sync::Mutex;
13pub struct ThreadPool{
15 workers: Vec<Worker>,
16 sender: mpsc::Sender<Job>,
17}
18
19impl ThreadPool{
20 pub fn new(size: usize) -> ThreadPool{
22 assert!(size > 0);
23 let (sender, receiver) = mpsc::channel();
24 let receiver = Arc::new(Mutex::new(receiver));
25 let mut workers = Vec::with_capacity(size);
26 for id in 0..size {
27 workers.push(Worker::new(id, Arc::clone(&receiver)));
28 }
29 ThreadPool{workers, sender}
30 }
31 pub fn execute<F>(&self, f:F)
33 where
34 F: FnOnce() + Send + 'static,{
35 let job = Box::new(f);
36 self.sender.send(job).unwrap();
37 }
38}
39struct Worker{
40 id: usize,
41 thread: thread::JoinHandle<()>,
42}
43type Job = Box<dyn FnBox + Send + 'static>;
44
45impl Worker {
46 fn new(id:usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker{
47 let thread = thread::spawn(move || loop {
48 while let Ok(job) = receiver.lock().unwrap().recv(){
49
50 println!("Worker {} got a job; excuting.", id);
51 job.call_box();
53 }
54 });
55 Worker { id, thread }
56 }
57}
58trait FnBox{
59 fn call_box(self: Box<Self>);
60}
61impl <F: FnOnce()> FnBox for F {
62 fn call_box(self: Box<F>) {
63 (*self)()
64 }
65}