From 164c69bae8065c1a6b15309e93dfd9b1cd9668e7 Mon Sep 17 00:00:00 2001 From: Unisko PENG Date: Thu, 6 Apr 2023 17:59:15 +0800 Subject: [PATCH] Update Ch20 --- hello/src/lib.rs | 35 ++++++++------ ...ect_Building_a_Multithreaded_Web_Server.md | 47 +++++++++++++++++++ 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/hello/src/lib.rs b/hello/src/lib.rs index e12cc13..8d0d21a 100644 --- a/hello/src/lib.rs +++ b/hello/src/lib.rs @@ -5,7 +5,7 @@ use std::{ pub struct ThreadPool { workers: Vec, - sender: mpsc::Sender, + sender: Option>, } type Job = Box; @@ -31,7 +31,10 @@ impl ThreadPool { workers.push(Worker::new(id, Arc::clone(&receiver))); } - ThreadPool { workers, sender } + ThreadPool { + workers, + sender: Some, + } } pub fn execute(&self, f: F) @@ -40,7 +43,21 @@ impl ThreadPool { { let job = Box::new(f); - self.sender.send(job).unwrap(); + self.sender.as_ref().unwrap().send(job).unwrap(); + } +} + +impl Drop for ThreadPool { + fn drop(&mut self) { + drop(self.sender.take()); + + for worker in &mut self.workers { + println! ("关闭 worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } } } @@ -65,15 +82,3 @@ impl Worker { } } } - -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(); - } - } - } -} diff --git a/src/Ch20_Final_Project_Building_a_Multithreaded_Web_Server.md b/src/Ch20_Final_Project_Building_a_Multithreaded_Web_Server.md index ed42caf..0a0e8ce 100644 --- a/src/Ch20_Final_Project_Building_a_Multithreaded_Web_Server.md +++ b/src/Ch20_Final_Project_Building_a_Multithreaded_Web_Server.md @@ -1333,4 +1333,51 @@ impl Drop for ThreadPool { 为修复这个问题,咱们将需要 `ThreadPool` 的 `drop` 实现中的一个修改,以及其后的 `Worker` 循环中的一个修改。 +首选,咱们将把 `ThreadPool` 的 `drop` 实现,修改为在等待线程结束前显式地丢弃 `sender`。下面清单 20-23 给出了对 `ThreadPool` 显示丢弃 `sender` 的修改。为能将 `send` 从 `ThreadPool` 迁出,咱们使用了与咱们曾对线程做过的同样 `Option` 于 `take` 技巧: +文件名:`src/lib.rs` + +```rust +pub struct ThreadPool { + workers: Vec, + sender: Option>, +} +// --跳过代码-- +impl ThreadPool { + pub fn new(size: usize) -> ThreadPool { + // --跳过代码-- + + ThreadPool { + workers, + sender: Some, + } + } + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + let job = Box::new(f); + + self.sender.as_ref().unwrap().send(job).unwrap(); + } +} + +impl Drop for ThreadPool { + fn drop(&mut self) { + drop(self.sender.take()); + + for worker in &mut self.workers { + println! ("关闭 worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } + } +} +``` + +*清单 20-23:在归拢那些 `worker` 线程前显式丢弃 `sender`* + +丢弃 `sender` 就会关闭通道,这表明将不会有其余消息发出。