V8 项目和 libuv 项目是 NodeJS 最重要的两个依赖项。
我认为在进入节点事件循环之前对什么是线程有一个基本的了解是很重要的。
因此,让我们将线程视为需要由 CPU 执行的指令的待办事项列表,CPU 将从上到下一个接一个地运行这些线程。单个进程内部可以有多个线程。
要了解线程,还必须了解一个称为调度的概念,因为您的 CPU 每秒只能处理这么多指令。
现在V8、libuv和Event Loop之间是什么关系?
嗯,我建立的V8和libuv都是NodeJS的依赖,这使得JavaScript可以在浏览器之外运行。每当我们在计算机上启动 Node 程序时,Node 会自动启动一个线程并在该线程内执行一些代码。在单个线程内部有一个称为事件循环的东西,可以将其视为一种控制结构,它决定我们的一个线程在任何时间点应该做什么。
它是任何Node程序的绝对核心,每个Node程序都有一个Event Loop。
所以:
事件循环是 libuv 还是 v8 的一部分?
是的,事件循环来自 Node 启动的进程,该进程具有 V8 和 libuv 作为依赖项。
事件队列是事件循环的一部分吗?事件队列是由 libuv 或 v8 引擎还是事件循环本身生成的?
事件队列,如果我理解这个问题更多地归结为您的操作系统调度程序。它决定哪些是最紧急的任务并首先运行。
libuv和v8引擎有什么联系?
嗯,它们都是 NodeJS 的依赖项,都是用 C++ 编写的,V8 是 70% C++,libuv 是 100% C++。
如果事件循环是单线程的,libuv 是否可以创建多个线程来处理文件 I/O?
所以这可能会造成混淆,Node 事件循环 是单线程的,但一些 Node 标准库 模块和一些框架不是单线程的。
libuv 库使 Node 能够访问您的操作系统。 libuv 模块和 C++ 端使用线程池。它可用于运行计算量大的任务。
默认情况下,libuv 在线程池中创建四个线程。除了事件循环中使用的线程之外,还有四个其他线程可用于卸载需要在应用程序内部进行的昂贵计算。
Node 标准库中的许多函数都使用了这个线程池。所以是的,libuv 出现在图片中以创建一个由四个线程组成的线程池。因此,libuv 提供了一个线程池,用于卸载需要在非常昂贵的函数调用上完成的工作。
浏览器有事件循环机制还是只有 Node.js 有?
我只知道 NodeJS 内部的事件循环机制。
总之,我们有一台 2015 年的双核 MacBook Pro。想象一下,您运行两个计算量大的函数,第一个在线程池内的第一个线程上运行,它通过 OS 调度程序 并到达第一个 CPU 核心。然后第二个函数被分配给池中的第二个线程,并被分配给第二个 CPU 内核。所以线程池发生在 libuv 内部。
有一点很重要,如果您正在发出http 请求,libuv 会看到这一点,并且 libuv 和 Node 都没有任何代码来处理所有超低级别涉及网络请求的操作。而是 libuv 将 http 请求委托给底层操作系统。
在这种情况下,libuv 用于向操作系统发出请求,并等待操作系统发出返回请求的响应。因此,因为 libuv 将此委托给您的操作系统,所以由您的操作系统决定是否添加新线程。这是一个 http 请求,我们不受 libuv 的四线程线程池的限制。所有的工作都由操作系统自己完成,我们根本没有接触线程池。