为什么在Rust中实现异步代码是特别困难?
💡
原文中文,约2500字,阅读约需6分钟。
📝
内容提要
本文讨论了异步 Rust 的困难之处,以及 Tokio 的使用和多线程调度程序的问题。Rust 的设计牺牲了抗阻塞性,以获得可嵌入性和极高性能。使用 epoll 和显式状态机可以更高效地处理一些情况。
🎯
关键要点
- 异步 Rust 的使用比 Go 或线程更困难,尤其是在 CPU 密集型操作中。
- Rust 的阻塞比 Go 的阻塞更有害,因为 Rust 生成新线程的难度更大。
- Go 和 Erlang 等语言使用绿色线程,隐式调用调度程序以解决阻塞问题,但会带来 CPU 开销。
- Rust 的设计牺牲了抗阻塞性,以获得可嵌入性和极高性能。
- Tokio 默认使用多线程和抢工调度,但在单线程模式下,阻塞会导致所有任务等待。
- 多线程调度可以稍微缓解阻塞问题,但仍然可能因长时间运行的操作而阻塞所有线程。
- Solaris 操作系统的轻量级线程技术为 IO 阻塞提供了优势,后来出现的 epoll 和 kqueue 提供了更好的异步 IO 方法。
- JavaScript 和 Python 的异步库在与其他库的集成上存在问题。
- Rust 的作用域线程允许函数调度并共享调用者堆栈中的引用,避免了 GC 和执行器池的复杂性。
- 使用 epoll 和显式状态机可以更高效地处理高并发的 IO 请求。
- 在 Rust 和 Tokio 中,线程和消息传递的设计不够直观,导致代码复杂且难以阅读。
➡️