1use std::{
15 sync::{mpsc, Arc, Mutex},
16 thread,
17};
18
19type Res<T> = Result<T, Box<dyn std::error::Error>>;
20
21type Job = Box<dyn FnOnce() + Send + 'static>;
22
23#[allow(dead_code)]
24pub struct ThreadPool {
25 workers: Vec<Worker>,
26 sender: mpsc::Sender<Job>,
27}
28
29#[allow(dead_code)]
30struct Worker {
31 id: usize,
32 thread: thread::JoinHandle<()>,
33}
34
35impl ThreadPool {
36 pub fn new(size: usize) -> ThreadPool {
37 assert!(size > 0);
38
39 let (sender, receiver) = mpsc::channel();
40
41 let receiver = Arc::new(Mutex::new(receiver));
42
43 let mut workers = Vec::with_capacity(size);
44
45 for id in 0..size {
46 workers.push(Worker::new(id, Arc::clone(&receiver)));
47 }
48
49 ThreadPool { workers, sender }
50 }
51
52 pub fn execute<F>(&self, f: F) -> Res<()>
53 where
54 F: FnOnce() + Send + 'static,
55 {
56 let job = Box::new(f);
57
58 self.sender.send(job)?;
59
60 Ok(())
61 }
62}
63
64impl Worker {
65 fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
66 let thread = thread::spawn(move || loop {
67 if let Ok(reciever_channel) = receiver.lock() {
68 if let Ok(job) = reciever_channel.recv() {
69 job();
70 }
71 }
72 });
73
74 Worker { id, thread }
75 }
76}