具有 Sync
和 Send
特征的可扩展并发
有趣的是,Rust 语言的并发功能非常少。几乎 到目前为止,我们在本章中讨论的每个并发功能都是 是标准库的一部分,而不是语言的一部分。您的处理选项 并发性不限于语言或标准库;您可以 编写您自己的并发功能或使用其他人编写的功能。
但是,语言中嵌入了两个并发概念:traits 和 .std::marker
Sync
Send
允许使用 send
在线程之间转移所有权
marker trait 表示
implementation 可以在线程之间传输。几乎所有 Rust 类型
是 ,但也有一些例外,包括 :这不能是因为如果您克隆了一个值并尝试转移所有权
克隆到另一个线程时,两个线程都可能会更新引用计数
同时。因此, 实现用于
您不想支付线程安全费用的单线程情况
性能损失。Send
Send
Send
Rc<T>
Send
Rc<T>
Rc<T>
因此,Rust 的类型系统和 trait 边界确保你永远不能
意外地以不安全的方式跨线程发送值。当我们尝试做
在示例 16-14 中,我们收到了错误 .当我们切换到 ,也就是 时,代码
编译。Rc<T>
the trait Send is not implemented for Rc<Mutex<i32>>
Arc<T>
Send
任何完全由类型组成的类型都会自动标记为
井。几乎所有原始类型都是 ,除了原始指针,它
我们将在第 19 章中讨论。Send
Send
Send
允许使用 Sync
从多个线程访问
marker trait 表示从多个线程引用类型 implementation 是安全的。换句话说,任何类型的都是 if (对 ) 的不可变引用 ) 是 ,表示引用
可以安全地发送到另一个线程。与 类似,基元类型 是 ,完全由类型组成的类型也是 。Sync
Sync
T
Sync
&T
T
Send
Send
Sync
Sync
Sync
智能指针也不是 .类型(我们在第 15 章中讨论过)和
family 的 不是 。borrow 的实现
在运行时执行的检查不是线程安全的。智能
pointer 是并且可用于与多个
您在 “在多个之间共享互斥<T>
中看到的线程
Threads“ 部分。Rc<T>
Sync
Send
RefCell<T>
Cell<T>
Sync
RefCell<T>
Mutex<T>
Sync
手动实现 Send
和 Sync
是不安全的
因为由 和 trait 组成的类型会自动
此外 和 ,我们不必手动实施这些特征。如
marker trait 中,它们甚至没有任何方法可以实现。他们只是
对于强制实施与并发相关的不变量很有用。Send
Sync
Send
Sync
手动实现这些 trait 涉及实现不安全的 Rust 代码。
我们将在第 19 章讨论使用不安全的 Rust 代码;目前,重要的
信息是,构建不是由 PARTS 组成的新的 concurrent types 需要仔细考虑以维护安全保证。“这
Rustonomicon“提供了有关这些保证以及如何
维护他们。Send
Sync
总结
这并不是您在本书中看到的最后一个并发:项目中的 第 20 章将在更现实的情况下使用本章中的概念 比这里讨论的较小示例。
如前所述,因为 Rust 处理并发的方式很少是 作为语言的一部分,许多并发解决方案都以 crate 的形式实现。 这些库比标准库发展得更快,因此请务必搜索 online 用于多线程中使用的当前最先进的 crate 情况。
Rust 标准库提供了消息传递和智能
可以安全使用的指针类型(如 和 )
并发上下文。类型系统和借用检查器确保
使用这些解决方案的代码不会以数据争用或无效引用结束。
一旦你让你的代码开始编译,你就可以放心了,它会很高兴
在多个线程上运行,而不会出现
其他语言。并发编程不再是一个令人恐惧的概念:
勇往直前,让你的程序同时进行,无所畏惧!Mutex<T>
Arc<T>
接下来,我们将讨论对问题进行建模和构建解决方案的惯用方法 随着你的 Rust 程序变得更大。此外,我们将讨论 Rust 的惯用语 与您可能熟悉的面向对象编程相关的内容相关联。
本文档由官方文档翻译而来,如有差异请以官方英文文档(https://doc.rust-lang.org/)为准