use std::{ sync::{mpsc, Arc, Mutex}, thread, }; pub struct ThreadPool { workers: Vec, sender: mpsc::Sender, } type Job = Box; impl ThreadPool { /// 创建出一个新的 ThreadPool。 /// /// 其中的 size 为线程池中线程的数目。 /// /// # 终止运行 /// /// 这个 `new` 函数将在 size 为零时终止运行。 pub fn new(size: usize) -> ThreadPool { assert! (size > 0); let (sender, receiver) = mpsc::channel(); let receiver = Arc::new(Mutex::new(receiver)); let mut workers = Vec::with_capacity(size); for id in 0..size { workers.push(Worker::new(id, Arc::clone(&receiver))); } ThreadPool { workers, sender } } pub fn execute(&self, f: F) where F: FnOnce() + Send + 'static, { let job = Box::new(f); self.sender.send(job).unwrap(); } } struct Worker { id: usize, thread: Option>, } impl Worker { fn new(id: usize, receiver: Arc>>) -> Worker { let thread = thread::spawn(move || loop { let job = receiver.lock().unwrap().recv().unwrap(); println! ("Worker {id} 获取到一项作业;执行中。"); job(); }); Worker { id, thread: Some(thread), } } } impl Drop for ThreadPool { fn drop(&mut self) { for worker in &mut self.workers { println! ("关闭 worker {}", worker.id); if let Some(thread) = worker.thread.take() { thread.join().unwrap(); } } } }