mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2025-03-14 03:10:44 +08:00
Update Ch20
This commit is contained in:
parent
9b46dc2e4b
commit
4a1fdc6d39
@ -1139,8 +1139,28 @@ Worker 1 获取到一项作业;执行中。
|
||||
|
||||
> 注意:若咱们在多个窗口同时打开 `/sleep`,他们可能会在设置的时间间隔每次加载一个。有些 web 浏览器会出于缓存原因,而顺序执行同一请求的多个实例。这样的局限并不是由咱们的服务器导致的。
|
||||
|
||||
在了解了第 18 章中的 `while let` 循环后,咱们可能想知道,为何咱们没有如下清单 20-21 中所示的那样,编写 `worker` 线程的代码。
|
||||
|
||||
文件名:`src/lib.rs`
|
||||
|
||||
这段代码将会编译及运行,但不会产生所需的线程行为:慢速请求仍将导致别的请求等待被处理。至于原因则有点微妙:由于锁的所有权是基于 `lock` 方法返回的 `LockResult<MutexGuard<T>>` 中,`MutexGuard<T>` 的生命周期,因此这个 `Mutex` 结构体没有公开的 `unlock` 方法。在编译时,借用检查器可于随后,就除非咱们拿着 `Mutex` 所守卫的某项资源的锁,否则无法访问该项资源这一规矩强制加以检查。但是,若咱们没有注意到 `MutexGuard<T>` 的生命周期,那么这样的实现同样能导致锁相较预期被占用更长时间。
|
||||
```rust
|
||||
impl Worker {
|
||||
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
|
||||
let thread = thread::spawn(move || {
|
||||
while let Ok(job) = receiver.lock().unwrap().recv() {
|
||||
println! ("Worker {id} 获取到一项作业;执行中。");
|
||||
|
||||
由于在 `let` 之下,等号右侧的表达式中用到的任何临时值,都会在 `let` 语句结束时被立即丢弃,因此使用了 `let job = receiver.lock().unwrap().recv().unwrap();` 的清单 20-20 中代码是工作的。但是,`while let`(以及 `if let` 与 `match`) 则是在相关代码块结束前,不会丢弃那些临时值。在清单 20-21 中,
|
||||
job();
|
||||
}
|
||||
});
|
||||
|
||||
Worker { id, thread }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*清单 20-21:使用 `while let` 的一种 `Worker::new` 替代实现*
|
||||
|
||||
这段代码将会编译及运行,但不会产生所需的线程行为:慢速请求仍将导致别的请求等待被处理。至于原因则有点微妙:由于锁的所有权是基于 `lock` 方法返回的 `LockResult<MutexGuard<T>>` 中,`MutexGuard<T>` 的生命周期,因此这个 `Mutex` 结构体没有公开的 `unlock` 方法。在编译时,借用检查器可于随后,就除非咱们拿着 `Mutex` 所守卫的某项资源的锁,否则无法访问该项资源这一规则强制加以检查。但是,若咱们没有注意到 `MutexGuard<T>` 的生命周期,那么这样的实现同样能导致锁相较预期被占用更长时间。
|
||||
|
||||
由于在 `let` 之下,等号右侧的表达式中用到的任何临时值,都会在 `let` 语句结束时被立即丢弃,因此使用了 `let job = receiver.lock().unwrap().recv().unwrap();` 的清单 20-20 中代码是工作的。但是,`while let`(以及 `if let` 与 `match`) 则是在相关代码块结束前,不会丢弃那些临时值。在清单 20-21 中,锁会在到 `job()` 的调用其将保持被持有,这意味着别的 `worker` 就没法收到作业。
|
||||
|
Loading…
Reference in New Issue
Block a user