【问题标题】:Does asyncronous I/O consume threads?异步 I/O 是否消耗线程?
【发布时间】:2013-12-11 11:14:41
【问题描述】:

我正在尝试了解 akka 演员并确定他们的好处。我知道许多参与者可以共享同一个线程,从而获得巨大的效率 - 但是在 Web 应用程序的上下文中,Web 容器应该在请求之间做同样的事情对吗?

因此好处可以归结为 I/O - 阻塞 I/O 会暂停线程以供其他人使用。

异步 ​​I/O 是否消耗线程?当我获得某个 I/O 结果的未来时,是否会在该 I/O 完成时使用线程?

【问题讨论】:

    标签: scala scalability akka reactive-programming


    【解决方案1】:

    here 对 Java 异步 I/O 模型的描述很容易掌握。基本思想是有一个内部线程池,它从内核检索完成的 I/O 通知,然后分派给其他线程以对其执行所需的操作。

    所以,从某种意义上说,是的,它使用线程。这里还有一点需要考虑:一切都是如此。那里的每一个软件都需要一个进程,在某个时候,检查一个 I/O 是否已经完成,以便它可以对其执行后续任务(好吧,它可能是即发即弃的,但那是对实际诉讼有所限制)。在以异步 I/O 闻名的 nodejs 上,该线程称为“事件循环”(尽管整体模型非常不同)。

    这里的重点是每个 I/O 操作没有一个线程对应。相反,有一个内部线程池负责接收所有异步 I/O 完成事件,然后在完成时采取任何所需的操作。

    也许更好的问题是:Java 中的异步 I/O 消耗的线程是否与正在处理的 I/O 请求的数量成比例?不,它没有;它消耗固定数量的线程。更有用的问题:在 Java 中启动异步 I/O 时,是否会阻塞启动 I/O 的线程?不,不是的;它立即返回。以及与该主题相关的问题:Java 中的异步 I/O 是否使用参与者线程池中的线程?不,它没有。

    接下来,到异步 I/O 返回的未来。当 I/O 未完成时,不会使用任何线程。但是,有一个 线程池 分配给该未来的完成,并且当 I/O 完成时,该池中的一个线程将用于执行与该未来的完成相关联的操作.完成这些操作后,线程将返回到该线程池。该线程池可能与演员使用的线程池不同(尽管我想可能有办法做到这一点)。

    【讨论】:

    • 我相信akka的implict val exec = context.dispatcher表示IO结果会在同一个线程池中检索。我曾考虑改变我的问题以更清楚地了解比例性,但也许您的答案是“不,它不消耗线程,但它确实使用线程”。标记为答案,因为它很深入。
    • @Stephen 可能有一个隐式,但 Java 不使用隐式,所以它会忽略它。如果您使用其他库中的异步 i/o,则必须检查其自己的文档。
    • 太棒了——完全忘记了 Akka 也是一个 Java 库;)。大概你仍然可以使用context.dispatcher 来执行Future 吗?
    • @Stephen 是的,但请注意 Scala Future 确实使 I/O 异步!如果您执行Future { blockingIO() } 之类的操作,您将在 I/O 上获得一个线程阻塞。不过,您可以使用 Promise 创建 Future 并将其与异步回调结合起来。
    【解决方案2】:

    TL;DR 接受的答案:不,异步 I/O 不消耗线程,但使用线程从内核。

    另外,来自Play Framework: async I/O without the thread pool and callback hell

    在事件服务器上,等待 I/O 非常便宜:空闲请求的成本可以忽略不计,因为它们不会占用线程。

    【讨论】:

    • 是的,这是正确的——但它只适用于非阻塞 I/O。你不能简单地通过在上面撒一些 Akka 魔法来将阻塞 I/O 变成非阻塞 I/O——它不是那样工作的。这是 node.js 社区中的一个众所周知的问题,它导致许多库被重写以执行异步 I/O。令人惊讶的是,在 JVM 世界中,没有与 JDBC 等效的异步数据库访问,尽管少数数据库具有可从 Java 和 Scala 使用的异步 API。
    • 顺便说一下通过在上面撒点魔法将阻塞 IO 变成非阻塞 IO——这就是 gevent 的全部意义,当然是在 python 世界中。跨度>
    • @om-nom-nom 谢谢,有趣!我正在考虑为此使用元编程 - 但以一种非常不同的方式。另一个值得研究的想法!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    相关资源
    最近更新 更多