可扩展并发与SyncSend性状

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

但是,该语言中嵌入了两个并发概念:std::marker性状SyncSend.

允许在线程之间转移所有权Send

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

因此,Rust 的类型系统和 trait 边界确保你永远不能 不小心发送了Rc<T>值。当我们尝试做 this 在示例 16-14 中,我们得到了the trait Send is not implemented for Rc<Mutex<i32>>.当我们切换到Arc<T>,即Send中,代码 编译。

完全由Sendtypes 会自动标记为Send如 井。几乎所有原始类型都是Send,除了原始指针之外,它 我们将在第 19 章中讨论。

允许从多个线程访问Sync

Syncmarker trait 表示它对于实现Sync从多个线程引用。换句话说,任何类型TSync如果&T(对T) 是Send,表示引用 可以安全地发送到另一个线程。似Send,基元类型为Sync,以及完全由以下类型组成的类型Sync也是Sync.

智能指针Rc<T>也不是Sync原因与事实并非如此Send.这RefCell<T>type(我们在第 15 章中讨论过)和 亲属Cell<T>类型不是Sync.borrow 的实现 检查RefCell<T>does 不是线程安全的。智能 指针Mutex<T>Sync,并可用于与多个 线程,如“共享Mutex<T>多个之间 线程”部分。

实施SendSync手动不安全

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

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

总结

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

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

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

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

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