]>
Commit | Line | Data |
---|---|---|
923072b8 FG |
1 | use std::{ |
2 | sync::{mpsc, Arc, Mutex}, | |
3 | thread, | |
4 | }; | |
74b04a01 XL |
5 | |
6 | pub struct ThreadPool { | |
7 | workers: Vec<Worker>, | |
8 | sender: mpsc::Sender<Job>, | |
9 | } | |
10 | ||
11 | type Job = Box<dyn FnOnce() + Send + 'static>; | |
12 | ||
13 | impl ThreadPool { | |
14 | /// Create a new ThreadPool. | |
15 | /// | |
16 | /// The size is the number of threads in the pool. | |
17 | /// | |
18 | /// # Panics | |
19 | /// | |
20 | /// The `new` function will panic if the size is zero. | |
21 | pub fn new(size: usize) -> ThreadPool { | |
22 | assert!(size > 0); | |
23 | ||
24 | let (sender, receiver) = mpsc::channel(); | |
25 | ||
26 | let receiver = Arc::new(Mutex::new(receiver)); | |
27 | ||
28 | let mut workers = Vec::with_capacity(size); | |
29 | ||
30 | for id in 0..size { | |
31 | workers.push(Worker::new(id, Arc::clone(&receiver))); | |
32 | } | |
33 | ||
34 | ThreadPool { workers, sender } | |
35 | } | |
36 | ||
37 | pub fn execute<F>(&self, f: F) | |
38 | where | |
39 | F: FnOnce() + Send + 'static, | |
40 | { | |
41 | let job = Box::new(f); | |
42 | ||
43 | self.sender.send(job).unwrap(); | |
44 | } | |
45 | } | |
46 | ||
47 | struct Worker { | |
48 | id: usize, | |
49 | thread: thread::JoinHandle<()>, | |
50 | } | |
51 | ||
52 | // ANCHOR: here | |
53 | // --snip-- | |
54 | ||
55 | impl Worker { | |
56 | fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker { | |
57 | let thread = thread::spawn(move || loop { | |
58 | let job = receiver.lock().unwrap().recv().unwrap(); | |
59 | ||
923072b8 | 60 | println!("Worker {id} got a job; executing."); |
74b04a01 XL |
61 | |
62 | job(); | |
63 | }); | |
64 | ||
65 | Worker { id, thread } | |
66 | } | |
67 | } | |
68 | // ANCHOR_END: here |