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

Confusion about node.js internal asynchronous I/O mechanism

本文关键字:机制 node js 内部 异步 关于      更新时间:2023-09-26
  1. 我了解到node.js内部使用libeio在*nix平台上使用线程池执行异步文件I/O,对吗
  2. 异步网络I/O怎么样?是利贝夫做的吗?还有线程池吗
  3. 如果里面有线程池,它怎么可能比传统的每个请求一个线程的模型更高效呢?是不是每个I/O请求一个线程
  4. 窗户上的机制是什么?我知道它是由IOCP完成的,并且有一个内核级别的线程池,对吧
  5. 为什么linux还没有像windowsIOCP那样的本机完全AIO机制?将来会有吗

根据昌昌的回答更新:

  1. 我快速查看了@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-vgrep只看到两个:

    root 16148 7492 16148 0 2 20:43分/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/note/home/aaron/workspace/test.js

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

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

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

Uptil版本0.6节点使用libev运行事件循环,使用libeio运行异步I/O(Unix后端主要依赖于这两个库(。但是libuv已经开始取代版本0.8中的libevlibeio。它执行、维护和管理事件池中的所有io和事件。libuv是跨平台异步IO库的选择。

  1. 是,高达节点0.6,在0.8中不推荐使用,并使用线程池
  2. 是,但libev不使用线程池。参见此处

    澄清:根据我发布的问题中的链接,libeio确实支持所有处理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确实显示了所有线程和进程,也许您过度过滤了它,只需查找像ps -eLf | grep x这样的节点进程pid,其中x是节点进程的pid。