为内核代码采用 Rust

Linux 允许在内核开发中使用 Rust 的举措,引发了关于它能否安全且高效地替代一些长期存在的 C 代码的争论,尤其是在内存安全 bug 常见的驱动程序领域。支持者强调 Rust 的所有权模型、强静态检查和 no_std 能力,是在不牺牲性能的前提下进行更安全系统编程的强大工具;批评者则指出编译时间较慢、`unsafe` 代码的复杂性,以及对 LLVM 和 C++ 工具链依赖的担忧。Zig 等替代方案被提及为在理念上更接近“C 文化”,但 Rust 的相对成熟度以及在底层系统中的现有生产使用,使其成为内核逐步采用的领先候选者。

C→Rust 迁移经验

  • 迁移者表示,Rust 迫使人们更深入地思考数据所有权、生命周期,以及“多个读者,一个写者”的模式。
  • 即使之后再写 C,这种转变也会改进设计。
  • 通过 Result/Optionmatch 进行错误处理、内联测试以及文档工具,被视为显著的生产力提升。
  • 几个人声称,Rust 代码库明显更简洁,也比对应的 C 代码更不脆弱。

动态数据与 JSON 处理

  • 有人认为,Rust 会让高度动态的任务(例如运行时 JSON schema、未知数据库表)比动态语言“稍微更难”。
  • 其他人则认为这主要只是额外的冗长,而不是真正的限制,并指出已有 crate 可用于运行时 JSON-schema 验证。

编译时间性能

  • 抱怨:与 C 相比,Rust 编译时间“糟糕透顶”,会让人望而却步。
  • 反驳观点:
    • 对于中等规模项目,干净构建在普通笔记本上几分钟内即可完成。
    • 与 C++ 相比,一旦功能集相近,Rust 的编译通常一样快甚至更快。
    • 过重的依赖树以及 trait/macro 最拖慢编译时间;内核中的 Rust(no_std、依赖很少)应该会表现更好。
  • 对比 Rust 和 C coreutils 的基准测试显示,构建时间大致在 2 倍因子内,具体取决于是否计算了哪些准备工作。
  • 有观点认为,单靠单态化并不是主要罪魁祸首;若要获得显著提升,需要一种根本不同的语言设计。

内核与系统编程中的 Rust

  • 强烈的热情:Rust 的内存安全被认为对驱动程序至关重要,因为并发 bug 和不安全模式非常普遍。
  • 引用的证据显示,内核中的内存安全 bug 的新增速度快于修复速度;因此有人把 Rust 作为一种结构性缓解手段提出。
  • 怀疑者:
    • 质疑 Rust 适不适合裸机和超低延迟系统,并不喜欢依赖基于 C++ 的 LLVM。
    • 有些人更偏好 Zig,因为它在文化上更接近 C,也更排斥大型工具链依赖,但他们也承认 Zig 目前还不够稳定。
    • 一次在 Rust 中进行低延迟交易的尝试报告称,最后那 20% 的性能关键部分在安全 Rust 中极其难做;unsafe 感觉比 C 更危险。
  • 支持者回应说:
    • 大多数底层工作都可以隔离在很小的 unsafe 片段中,其余部分则受益于安全性。
    • Rust 可以在与 C 类似的抽象层级上运行(尤其是使用 no_std 时),同时在合适的时候仍可提供高层、零成本抽象。

工具链与 LLVM/GCC

  • 内核越来越多地使用 Clang 构建;问题仍然存在,但工具链竞争被视为有益。
  • 有人抱怨在没有 GCC/binutils/glibc 的情况下 LLVM 很难构建;也有人认为这是小众关切,并指出 GCC 也依赖 C++。