无畏并发
安全且高效的处理并发编程是 Rust 的另一个主要目标。并发编程(Concurrent programming),代表程序的不同部分相互独立的执行,而 并行编程(parallel programming)代表程序不同部分于同时执行,这两个概念随着计算机越来越多的利用多处理器的优势时显得愈发重要。由于历史原因,在此类上下文中编程一直是困难且容易出错的:Rust 希望能改变这一点。
起初,Rust 团队认为确保内存安全和防止并发问题是两个分别需要不同方法应对的挑战。随着时间的推移,团队发现所有权和类型系统是一系列解决内存安全 和 并发问题的强有力的工具!通过利用所有权和类型检查,在 Rust 中很多并发错误都是 编译时 错误,而非运行时错误。因此,相比花费大量时间尝试重现运行时并发 bug 出现的特定情况,Rust 会拒绝编译不正确的代码并提供解释问题的错误信息。因此,你可以在开发时修复代码,而不是在部署到生产环境后修复代码。我们给 Rust 的这一部分起了一个绰号 无畏并发(fearless concurrency)。无畏并发令你的代码免于出现诡异的 bug 并可以轻松重构且无需担心会引入新的 bug。
注意:出于简洁的考虑,我们将很多问题归类为 并发,而不是更准确的区分 并发和(或)并行。如果这是一本专注于并发和/或并行的书,我们肯定会更加精确的。对于本章,当我们谈到 并发 时,请自行脑内替换为 并发和(或)并行。
很多语言所提供的处理并发问题的解决方法都非常有特色。例如,Erlang 有着优雅的消息传递并发功能,但只有模糊不清的在线程间共享状态的方法。对于高级语言来说,只实现可能解决方案的子集是一个合理的策略,因为高级语言所许诺的价值来源于牺牲一些控制来换取抽象。然而对于底层语言则期望提供在任何给定的情况下有着最高的性能且对硬件有更少的抽象。因此,Rust 提供了多种工具,以符合实际情况和需求的方式来为问题建模。
如下是本章将要涉及到的内容:
- 如何创建线程来同时运行多段代码。
- 消息传递(Message passing)并发,其中信道(channel)被用来在线程间传递消息。
- 共享状态(Shared state)并发,其中多个线程可以访问同一片数据。
Sync
和Send
trait,将 Rust 的并发保证扩展到用户定义的以及标准库提供的类型中。