具有 SyncSend 特征的可扩展并发

有趣的是,Rust 语言的并发功能非常少。几乎 到目前为止,我们在本章中讨论的每个并发功能都是 是标准库的一部分,而不是语言的一部分。您的处理选项 并发性不限于语言或标准库;您可以 编写您自己的并发功能或使用其他人编写的功能。

但是,语言中嵌入了两个并发概念:traits 和 .std::markerSyncSend

允许使用 send 在线程之间转移所有权

marker trait 表示 implementation 可以在线程之间传输。几乎所有 Rust 类型 是 ,但也有一些例外,包括 :这不能是因为如果您克隆了一个值并尝试转移所有权 克隆到另一个线程时,两个线程都可能会更新引用计数 同时。因此, 实现用于 您不想支付线程安全费用的单线程情况 性能损失。SendSendSendRc<T>SendRc<T>Rc<T>

因此,Rust 的类型系统和 trait 边界确保你永远不能 意外地以不安全的方式跨线程发送值。当我们尝试做 在示例 16-14 中,我们收到了错误 .当我们切换到 ,也就是 时,代码 编译。Rc<T>the trait Send is not implemented for Rc<Mutex<i32>>Arc<T>Send

任何完全由类型组成的类型都会自动标记为 井。几乎所有原始类型都是 ,除了原始指针,它 我们将在第 19 章中讨论。SendSendSend

允许使用 Sync 从多个线程访问

marker trait 表示从多个线程引用类型 implementation 是安全的。换句话说,任何类型的都是 if (对 ) 的不可变引用 ) 是 ,表示引用 可以安全地发送到另一个线程。与 类似,基元类型 是 ,完全由类型组成的类型也是 。SyncSyncTSync&TTSendSendSyncSyncSync

智能指针也不是 .类型(我们在第 15 章中讨论过)和 family 的 不是 。borrow 的实现 在运行时执行的检查不是线程安全的。智能 pointer 是并且可用于与多个 您在 “在多个之间共享互斥<T> 中看到的线程 Threads“ 部分。Rc<T>SyncSendRefCell<T>Cell<T>SyncRefCell<T>Mutex<T>Sync

手动实现 SendSync 是不安全的

因为由 和 trait 组成的类型会自动 此外 和 ,我们不必手动实施这些特征。如 marker trait 中,它们甚至没有任何方法可以实现。他们只是 对于强制实施与并发相关的不变量很有用。SendSyncSendSync

手动实现这些 trait 涉及实现不安全的 Rust 代码。 我们将在第 19 章讨论使用不安全的 Rust 代码;目前,重要的 信息是,构建不是由 PARTS 组成的新的 concurrent types 需要仔细考虑以维护安全保证。“这 Rustonomicon“提供了有关这些保证以及如何 维护他们。SendSync

总结

这并不是您在本书中看到的最后一个并发:项目中的 第 20 章将在更现实的情况下使用本章中的概念 比这里讨论的较小示例。

如前所述,因为 Rust 处理并发的方式很少是 作为语言的一部分,许多并发解决方案都以 crate 的形式实现。 这些库比标准库发展得更快,因此请务必搜索 online 用于多线程中使用的当前最先进的 crate 情况。

Rust 标准库提供了消息传递和智能 可以安全使用的指针类型(如 和 ) 并发上下文。类型系统和借用检查器确保 使用这些解决方案的代码不会以数据争用或无效引用结束。 一旦你让你的代码开始编译,你就可以放心了,它会很高兴 在多个线程上运行,而不会出现 其他语言。并发编程不再是一个令人恐惧的概念: 勇往直前,让你的程序同时进行,无所畏惧!Mutex<T>Arc<T>

接下来,我们将讨论对问题进行建模和构建解决方案的惯用方法 随着你的 Rust 程序变得更大。此外,我们将讨论 Rust 的惯用语 与您可能熟悉的面向对象编程相关的内容相关联。

本文档由官方文档翻译而来,如有差异请以官方英文文档(https://doc.rust-lang.org/)为准