Rust中使用io_uring实现异步并不安全


由Tzu Gwo在2024年10月30日发表。以下是文章的主要内容摘要:

摘要

  • 文章通过一个示例展示了在使用io_uring驱动时TCP连接会泄露,而在epoll驱动时则不会。
  • 作者测试了多个支持io_uring的异步运行时,发现这是一个普遍问题。

Barbara的TCP连接神秘泄露

  • Barbara是一位有丰富经验的Rust异步Web服务开发者,她尝试将服务迁移到基于io_uring的版本。
  • 她选择了支持io_uring的monoio异步运行时,并快速编写了一个HTTP服务器示例。
  • 然而,她发现在使用异步控制(如超时)时,TCP连接出现了泄露问题,这个问题影响到了所有使用io_uring的异步运行时。

原因分析
文章解释了为什么使用“select”进行超时控制时,在基于io_uring的异步运行时会导致TCP连接泄露,而epoll则不会。

异步Rust的核心是Future,它定义了异步操作的状态。

  • epoll作为事件通知机制,遵循Future的假设,
  • 而io_uring作为异步系统调用机制,打破了这些假设。

解决方案

  • 文章将问题分为I/O安全和停止安全两部分,并提出了解决方案。
  • I/O安全可以通过Rust的Drop特性来解决,鼓励异步运行时实现这一修复。
  • 停止安全更为复杂,monoio提供了“可取消I/O”组件来处理io_uring绑定的Future的取消。

文章最后,作者提出了几个问题,询问读者对于I/O安全和停止安全的看法,是否应该由Rust语言来保证这些安全。
这篇文章提供了对Rust异步编程中io_uring使用的一个深入分析,特别是它与epoll的不同之处以及潜在的问题和解决方案。