【问题标题】:Confusion about node.js internal asynchronous I/O mechanism关于node.js内部异步I/O机制的困惑
【发布时间】:2013-03-09 17:23:12
【问题描述】:
  1. 我了解到 node.js 在内部使用 libeio 在 *nix 平台上使用线程池执行异步 file I/O,对吗?
  2. 异步网络 I/O 怎么样?它是由libev完成的吗?还有线程池吗?
  3. 如果里面有线程池,怎么会比传统的一个请求一个线程的模型更高效呢?每个 I/O 请求一个线程吗?
  4. Windows 的机制是什么?我知道是 IOCP 做的,还有内核级别的线程池,对吧?
  5. 为什么linux还没有像windows IOCP这样原生的完全AIO机制?以后会有吗?

根据长昌的回答更新:

  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
    根 16148 7492 16149 0 2 20:43 pts/26 00:00:00 ./bin/node /home/aaron/workspace/test.js

【问题讨论】:

  • node.js 实际上使用libuv 为所有支持的平台抽象异步IO
  • @user568109 我已经读过,但无法从中得到直接的答案,实际上,不清楚的表达更让我困惑。它提到 libeio '异步执行输入输出'包括套接字,我对此表示怀疑。我从某个地方了解到这一点:因为不能在常规文件上使用 epoll,所以这里有 libeio 来使用线程执行 aio。
  • @simfoo 是的,我知道 libuv,我想知道它下面的机制,包括 *nix 和 windows。

标签: javascript linux node.js io libuv


【解决方案1】:
  1. 首先,libuv 已从中删除了 libeio。但正如您所提到的,它确实使用像 libeio 这样的线程池执行异步文件 I/O。

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

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

【讨论】:

  • 坦克很多,很多资源都过时了,你刚刚救了我!
  • @AaronWang 如果它回答了你的问题,你应该接受它。
  • 首先:libuv [...] 执行异步网络 I/O [...] 没有线程池。后来:libuv 中的线程池[...]。这对我来说似乎是矛盾的。
  • 4 不是一个很小的数字,尤其是对于 io 绑定的任务。节点是否允许更改池大小?
  • ^ 是的,通过 UV_THREADPOOL_SIZE
【解决方案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

    澄清:根据我发布的question 中的linklibeio 确实支持所有处理 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)。

更新问题:

  1. 不太了解libuv
  2. 也许够了(不知道)
  3. 这是我在 Windows 8 上的发现,通过 Process Explorer 进行了检查。显示了一个节点应用程序进程的 4 个线程、1 个 DLL、1 个文件和 1 个部分(共 7 个条目)。

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

【讨论】:

    猜你喜欢
    • 2020-10-23
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多