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

根据changchang的回答更新:

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

    根 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

4

2 回答 2

30
  1. 首先,libuv已从中删除libeiolibeio但它确实像您提到的那样使用线程池执行异步文件 I/O 。

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

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

于 2013-03-21T08:39:19.323 回答
2

Uptil 0.6 版节点用于libev运行事件循环和libeio异步 I/O(Unix 后端大量依赖这两个库)。但libuv已开始替换libevlibeio0.8 版本中。它执行、维护和管理事件池中的所有 io 和事件。libuv是跨平台异步IO库的选择。

  1. 是的,直到节点 0.6,在 0.8 中已弃用并使用线程池
  2. 是的,但libev不使用线程池。看这里

    澄清:根据我发布的问题中的链接,确实支持处理 I/O(包括套接字)的所有 POSIX 函数。但是节点作者决定仅将其用于异步文件 I/O,并用于网络 I/O。我不知道你是从哪里听说的,但你可以在常规文件上使用 epoll。libeiolibev

  3. libev使用事件循环,所以这里没有问题。

  4. 是的IOCP在 Windows 中处理异步 I/O,内核确实使用线程池。
  5. 新的 linux 内核在新的 BSD 内核中有 epoll、kqueue。libev并且libeio适用于 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 一样。

于 2013-03-22T20:37:59.940 回答