mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2025-03-23 07:40:29 +08:00
Update Ch20
This commit is contained in:
parent
63b0ffc848
commit
164c69bae8
@ -5,7 +5,7 @@ use std::{
|
|||||||
|
|
||||||
pub struct ThreadPool {
|
pub struct ThreadPool {
|
||||||
workers: Vec<Worker>,
|
workers: Vec<Worker>,
|
||||||
sender: mpsc::Sender<Job>,
|
sender: Option<mpsc::Sender<Job>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Job = Box<dyn FnOnce() + Send + 'static>;
|
type Job = Box<dyn FnOnce() + Send + 'static>;
|
||||||
@ -31,7 +31,10 @@ impl ThreadPool {
|
|||||||
workers.push(Worker::new(id, Arc::clone(&receiver)));
|
workers.push(Worker::new(id, Arc::clone(&receiver)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadPool { workers, sender }
|
ThreadPool {
|
||||||
|
workers,
|
||||||
|
sender: Some<sender>,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute<F>(&self, f: F)
|
pub fn execute<F>(&self, f: F)
|
||||||
@ -40,7 +43,21 @@ impl ThreadPool {
|
|||||||
{
|
{
|
||||||
let job = Box::new(f);
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1333,4 +1333,51 @@ impl Drop for ThreadPool {
|
|||||||
|
|
||||||
为修复这个问题,咱们将需要 `ThreadPool` 的 `drop` 实现中的一个修改,以及其后的 `Worker` 循环中的一个修改。
|
为修复这个问题,咱们将需要 `ThreadPool` 的 `drop` 实现中的一个修改,以及其后的 `Worker` 循环中的一个修改。
|
||||||
|
|
||||||
|
首选,咱们将把 `ThreadPool` 的 `drop` 实现,修改为在等待线程结束前显式地丢弃 `sender`。下面清单 20-23 给出了对 `ThreadPool` 显示丢弃 `sender` 的修改。为能将 `send` 从 `ThreadPool` 迁出,咱们使用了与咱们曾对线程做过的同样 `Option` 于 `take` 技巧:
|
||||||
|
|
||||||
|
文件名:`src/lib.rs`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct ThreadPool {
|
||||||
|
workers: Vec<Worker>,
|
||||||
|
sender: Option<mpsc::Sender<Job>>,
|
||||||
|
}
|
||||||
|
// --跳过代码--
|
||||||
|
impl ThreadPool {
|
||||||
|
pub fn new(size: usize) -> ThreadPool {
|
||||||
|
// --跳过代码--
|
||||||
|
|
||||||
|
ThreadPool {
|
||||||
|
workers,
|
||||||
|
sender: Some<sender>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute<F>(&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` 就会关闭通道,这表明将不会有其余消息发出。
|
||||||
|
Loading…
Reference in New Issue
Block a user