【问题标题】:Converting a synchronous Rust IO driver to be `async`将同步 Rust IO 驱动程序转换为 `async`
【发布时间】:2020-12-07 11:15:36
【问题描述】:

我有一个UIO driver,它在所谓的wait_on_complete 函数中轮询文件描述符以等待中断。这是完全同步的,所以会阻塞(有超时)。我想迁移代码,使wait_on_completeasync(或者可以轻松包装以创建有用的Future),但我不确定最好的策略。

我对选项的看法是:

  1. 使用mio::Poll,据我了解,这意味着使用 Tokio 反应器,但我无法在 Tokio ^0.3 中遵循此 API。在 Tokio 0.2 中似乎有一个 few things around 这个,但它们已经消失了(尽管它似乎仍然在代码中 - 这只是缺少文档吗?)。
  2. 使用 polling 之类的东西,它带有自己的反应器。问题在于驱动程序似乎放错了反应堆的位置。
  3. 在自己的线程中运行同步代码并与async 通道通信。鉴于async 的要点之一是正确集成异步 IO,这在架构上似乎是一个糟糕的选择(实际上,IO 非常适合主状态机)。
  4. 还有一些我不知道的事情。

(1) 似乎是显而易见的解决方案,但我并不完全清楚如何去做。是否有一些关于创建自己的mio 设备并在 Tokio 运行时中使用它的最新文档?

还有没有其他方法可以让我做我想做的事?我是否在考虑中遗漏了什么?

【问题讨论】:

  • 大多数运行时都有一种方法来处理阻塞任务,方法是在单独的线程上运行它们。见tokio::spawn_blocking
  • @IbraheemAhmed 谢谢,我知道(这是我列表中 (3) 的假定机制)。

标签: asynchronous rust rust-tokio mio


【解决方案1】:

使用来自async-ioAsync 很容易做到这一点。

制作一个封装你的fd 的结构,为它实现AsRawFd,然后用Async 包装它。

这允许您使用read_withwrite_with 执行自定义异步操作。

【讨论】:

  • 这个看起来和Tokio approach很相似,我后来了解到的是当前的 Tokio 策略。 async-io 的情况下反应堆在哪里运行? (例如,它是否以某种方式依赖于运行时?)
  • Async 上有一个文档段落:“但是,不要将 Async 与 File、Stdin、Stdout 或 Stderr 等类型一起使用,因为所有操作系统在进入非阻塞模式时都会出现问题。”
  • async-io 产生自己的反应器线程,因此它不依赖于特定的运行时/执行器。它本身也是用于async-std 的反应器。
  • 如果您的 fd 是您使用 open() 从 UIO 设备获得的,那应该没问题。文件的问题在于将数据存储在文件系统上的“真实”文件。
  • 只是为了未来读者的完整性:Tokio 对反应器采用了不同的方法,因为它在执行程序线程中运行。哪个更好取决于用例。
猜你喜欢
  • 2012-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多