无畏并发
安全且高效地处理并发编程是 Rust 的另一个主要目标。并发编程(concurrent programming)指程序的不同部分独立执行,而并行编程(parallel programming)指程序的不同部分 同时执行。随着越来越多的计算机利用其多处理器, 这两者变得日益重要。从历史上看, 在这类场景中进行编程既困难又容易出错。Rust 希望改变 这一现状。
起初,Rust 团队认为确保内存安全和防止并发问题是两个 独立的挑战,需要用不同的方法来解决。随着时间的推移, 团队发现所有权系统和类型系统是一套强大的工具, 既能帮助管理内存安全,也能帮助解决并发 问题!通过利用所有权和类型检查,许多并发错误 在 Rust 中是编译时错误,而不是运行时错误。因此, 你无需花费大量时间试图重现运行时并发 bug 出现的 确切场景——不正确的代码将拒绝编译, 并给出解释问题的错误信息。这样一来, 你可以在编写代码时就修复问题, 而不是在代码可能已经发布到生产环境之后。 我们将 Rust 的这一特性称为无畏并发(fearless concurrency)。无畏并发让你编写的代码没有 难以察觉的 bug,并且易于重构而不引入新 bug。
注意:为简洁起见,我们将把许多问题统称为 并发(concurrent),而不是更精确地说并发和/或 并行(concurrent and/or parallel)。在本章中,每当我们使用 并发一词时,请在心中将其替换为并发和/或 并行。在下一章中,当这种区别更为重要时, 我们会更加具体地区分。
许多语言对于它们提供的并发问题解决方案持有教条式的立场。 例如,Erlang 拥有优雅的消息传递并发功能, 但在线程之间共享状态的方式却很晦涩。 只支持一部分可能的解决方案对于高级语言来说是一个合理的 策略,因为高级语言承诺通过放弃一些控制来换取抽象 带来的好处。然而,低级语言被期望在任何 给定情况下提供性能最佳的解决方案,并且对硬件的抽象 更少。因此,Rust 提供了各种工具, 让你能够以适合你场景和需求的任何方式来建模问题。
以下是本章将涵盖的主题:
- 如何创建线程来同时运行多段代码
- 消息传递(message-passing)并发,其中通道在线程之间发送消息
- 共享状态(shared-state)并发,其中多个线程可以访问某段 数据
Sync和Sendtrait,它们将 Rust 的并发保证扩展到 用户定义类型以及标准库提供的类型