From 33a684338f337fbc6756890c04f998c3b50d782f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BB=E8=AF=AD?= Date: Thu, 29 May 2025 22:27:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=BA=9B=E8=AF=AD?= =?UTF-8?q?=E5=8F=A5=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch16-03-shared-state.md | 4 ++-- src/ch16-04-extensible-concurrency-sync-and-send.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ch16-03-shared-state.md b/src/ch16-03-shared-state.md index 2ad2122..e325b11 100644 --- a/src/ch16-03-shared-state.md +++ b/src/ch16-03-shared-state.md @@ -38,7 +38,7 @@ 如果另一个线程拥有锁,并且那个线程 panic 了,则 `lock` 调用会失败。在这种情况下,没人能够再获取锁,所以我们调用 `unwrap`,使当前线程 panic。 -一旦获取了锁,就可以将返回值(命名为 `num`)视为一个其内部数据的可变引用了。类型系统确保了我们在使用 `m` 中的值之前获取锁。`m` 的类型是 `Mutex` 而不是 `i32`,所以**必须**调用 `lock` 才能使用这个 `i32` 值。我们不能忘记这么做的;因为如果没有获取锁,类型系统就不允许访问内部的 `i32` 值。 +一旦获取了锁,就可以将返回值(命名为 `num`)视为一个其内部数据的可变引用了。类型系统确保了我们在使用 `m` 中的值之前获取锁。`m` 的类型是 `Mutex` 而不是 `i32`,所以**必须**调用 `lock` 才能使用这个 `i32` 值。我们不能忘记这么做,因为如果没有获取锁,类型系统就不允许访问内部的 `i32` 值。 正如你所猜想的,`Mutex` 是一个智能指针。更准确的说,`lock` 调用会**返回**一个叫做 `MutexGuard` 的智能指针。`MutexGuard` 智能指针实现了 `Deref` 来指向其内部数据;它也实现了 `Drop`,当 `MutexGuard` 离开作用域时,自动释放锁(发生在示例 16-12 内部作用域的结尾)。这样一来,就不会有忘记释放锁从而导致互斥器阻塞无法被其他线程使用的潜在风险,因为锁的释放是自动发生的。 @@ -94,7 +94,7 @@ 所幸 `Arc` 正是这么一个类似 `Rc` 并可以安全地用于并发环境的类型。字母 _a_ 代表 **原子性**(_atomic_),所以这是一个**原子引用计数**(_atomically reference counted_)类型。**原子类型** (Atomics) 是另一类这里还未涉及到的并发原语:请查看标准库中 [`std::sync::atomic`][atomic] 的文档来获取更多细节。目前我们只需要知道:原子类型就像基本类型一样,可以安全地在线程间共享。 -你可能会好奇,为什么不是所有的基本类型都是原子性的?为什么标准库中的类型没有全部默认使用 `Arc` 实现?原因在于,线程安全会造成性能损失,我们希望只在必要时才为此买单。如果只是在单线程中对值进行操作,如果不必强制原子性所提供的保证可以使代码运行得更快。 +你可能会好奇,为什么不是所有的基本类型都是原子性的?为什么标准库中的类型没有全部默认使用 `Arc` 实现?原因在于,线程安全会造成性能损失,我们希望只在必要时才为此买单。如果只是在单线程中对值进行操作,不必强制原子性所提供的保证可以使代码运行得更快。 回到之前的例子:`Arc` 和 `Rc` 有着相同的 API,所以我们只需修改程序中的 `use` 行、`new` 调用和 `clone` 调用。示例 16-15 中的代码最终可以编译并运行。 diff --git a/src/ch16-04-extensible-concurrency-sync-and-send.md b/src/ch16-04-extensible-concurrency-sync-and-send.md index 9cf4b46..1fb723a 100644 --- a/src/ch16-04-extensible-concurrency-sync-and-send.md +++ b/src/ch16-04-extensible-concurrency-sync-and-send.md @@ -29,11 +29,11 @@ Rust 的并发模型中一个有趣的方面是:我们之前讨论的几乎所 ## 总结 -这不会是本书最后一个出现并发的章节:下一章会我们会专注于异步编程,并且第二十一章的项目会在更现实的场景中使用这些概念,而不像本章中讨论的这些小例子。 +这不会是本书最后一个出现并发的章节:下一章我们会专注于异步编程,并且第二十一章的项目会在更现实的场景中使用这些概念,而不像本章中讨论的这些小例子。 正如之前提到的,因为 Rust 本身很少有处理并发的部分内容,有很多的并发方案都由 crate 实现。它们比标准库要发展的更快;请在网上搜索当前最新的用于多线程场景的 crate。 -Rust 提供了用于消息传递的信道,和像 `Mutex` 和 `Arc` 这样可以安全的用于并发上下文的智能指针。类型系统和借用检查器会确保这些场景中的代码,不会出现数据竞争和无效的引用。一旦代码可以编译了,我们就可以坚信这些代码可以正确地运行于多线程环境,而不会出现其他语言中经常出现的那些难以追踪的 bug。并发编程不再是什么可怕的概念:无所畏惧地并发起来吧! +Rust 提供了用于消息传递的信道,和像 `Mutex` 和 `Arc` 这样可以安全的用于并发上下文的智能指针。类型系统和借用检查器会确保这些场景中的代码不会出现数据竞争和无效的引用。一旦代码可以编译了,我们就可以坚信这些代码可以正确地运行于多线程环境,而不会出现其他语言中经常出现的那些难以追踪的 bug。并发编程不再是什么可怕的概念:无所畏惧地并发起来吧! [sharing-a-mutext-between-multiple-threads]: ch16-03-shared-state.html#在多个线程间共享-mutext [nomicon]: https://doc.rust-lang.org/nomicon/index.html