关于node.js内部异步I / O机制的困惑

时间:2013-03-20 14:36:09

标签: javascript linux node.js io libuv

  1. 我了解到node.js在内部使用libeio来执行异步文件 I / O,带有线程池,在* nix平台上,我是对的吗?
  2. 异步网络 I / O怎么样?它是由libev完成的吗?还有线程池吗?
  3. 如果内部有线程池,那么它如何比传统的每线程请求模型更高效?并且每个I / O请求是一个线程吗?
  4. Windows上的机制是什么?我知道它是由IOCP完成的,并且有一个内核级线程池,对吧?
  5. 为什么linux没有像Windows IOCP这样的本机完全AIO机制呢?它将来会有吗?
  6. 根据昌昌的回答更新:

    1. 我快速查看source code @changchang给出的内容,发现默认的线程池大小可以通过 UV_THREADPOOL_SIZE 重置,我想知道在哪种情况下这将是用过的?
    2. 我还发现getaddrinfo使用这个线程池,除了fs还有吗?如果所有同步作业都将在此线程池中完成,那么默认大小“4”是否足够?
    3. 正如我现在的理解,node.js进程中将有6个基本线程:1个V8线程(事件循环,用户javascript代码运行),1个libuv事件循环,4个线程池,我是对的吗?
    4. 我怎样才能在shell(Ubuntu)中看到这些线程?我使用 ps -eLf | grep节点| grep -v grep 只看到两个:

      root 16148 7492 16148 0 2 20:43 pts / 26 00:00:00 ./bin/node /home/aaron/workspace/test.js
      root 16148 7492 16149 0 2 20:43 pts / 26 00:00:00 ./bin/node /home/aaron/workspace/test.js

2 个答案:

答案 0 :(得分:28)

  1. 首先,libuv已从中移除了libeio。但它确实像你提到的那样用libeio这样的线程池执行异步文件I / O.

  2. libuv也会移除libev。它基于不同平台中的异步I / O接口执行异步网络I / O,例如epollkqueueIOCP,没有线程池。有一个事件循环在uv的主线程上运行,它会轮询I / O事件并处理它们。

  3. libuv内的线程池是一个固定大小的线程池(4 in uinx like system)。它执行任务队列角色,并通过在请求增加时无限期地生成线程来避免系统资源耗尽。

答案 1 :(得分:2)

Uptil版本0.6节点使用libev来运行事件循环,libeio用于异步I / O,(Unix后端严重依赖于这两个库)。但libuv已开始替换version 0.8中的libevlibeio。它执行,保留和管理事件池中的所有io和事件。 libuv是跨平台异步IO库的选择。

  1. 是,最高节点0.6,弃用0.8并使用线程池
  2. 是的,但libev不使用线程池。见here

    澄清:根据我发布的link中的questionlibeio支持所有处理I / O(包括套接字)的POSIX函数。但节点作者决定仅将其用于异步文件I / O,并将libev用于网络I / O.我不知道你从哪里听到它,但你可以在普通文件上使用epoll。

  3. libev使用事件循环,因此没有问题。

  4. IOCP处理Windows中的异步I / O,内核确实使用线程池。
  5. 新的Linux内核在新的BSD内核中有epoll,kqueue。 libevlibeio用于linux环境,并为所有内核提供事件循环/异步IO(支持select,poll,epoll,kqueue)。
  6. 更新问题:

    1. libuv
    2. 了解不多
    3. 也许够(不知道)
    4. 以下是我在Windows 8上的调查结果,通过Process Explorer进行检查。为节点申请流程显示了4个主题,1个DLL,1个文件和1个部分(共7个条目)。

    5. ps -eLf确实显示了所有线程和进程,也许你过度过滤它,只需查找节点进程pid,如ps -eLf | grep x,其中x是节点进程的pid。