事件循环,libuv和v8引擎之间的关系

时间:2018-04-13 06:58:10

标签: javascript node.js v8 libuv

我正在学习Node.js的架构。我有以下问题。

  1. 事件循环是libuv还是v8的一部分?
  2. 事件队列是事件循环的一部分吗?是由libuv或v8引擎或事件循环本身生成的事件队列吗?
  3. libuv和v8引擎之间有什么联系?
  4. 如果事件循环是单线程的,libuv是否会进入图片以创建多个线程来处理文件I / O?
  5. 浏览器是否有事件循环机制或只有Node.js吗?

4 个答案:

答案 0 :(得分:7)

  1. 事件循环首先是一个高级概念,它是JavaScript编程模型的基本组成部分。实际上,每个V8嵌入器都需要实现一个事件循环。 V8提供了一个默认实现,嵌入器可以替换或扩展。

  2. 我不明白这个问题。 (我猜答案是"是的",但是"事件循环"和"事件队列"?)

    <之间的区别是什么? / LI>
  3. 无。 (除了Node.js使用两者。)

  4. 是的,事件循环是单线程的。

  5. 是的,浏览器也有一个事件循环(参见问题1)。

答案 1 :(得分:1)

这实际上并不像所选答案中给出的那么简单。我希望我的发言会更加准确。希望我在关于Node事件循环的演讲中正确理解了Sam Roberts(IBM)。

要自己查看谈话,您可以在这里:https://www.youtube.com/watch?v=P9csgxBgaZ8

这是@jmrk给出的答案的附加内容

Libuv将任务委派给基础操作系统。然后,操作系统将负责在您正在监听的事件发生时发送通知。它为您在Node中执行的许多操作执行此操作。如:套接字(net / dgram / http / tls / https / child_process管道,stdin,out,err),超时和间隔。

但是,并非所有事情都能像这样被延迟到底层操作系统。有时需要创建一个线程(默认情况下有4个踏步,但是您可以使用UV_THREADPOOL_SIZE进行更改)。文件系统操作,dns.lookup()和某些加密函数不可以轮询。

答案 2 :(得分:0)

请注意以下几点:-

  1. V8引擎是火车教练的引擎。它具有某些职责,包括提供事件循环以运行异步任务。

  2. 事件循环是执行异步任务的核心。 C ++ Web API一旦完成一个功能(任务),便会调用回调。回调将移至事件队列,并等待直到堆栈变空。因此,事件队列是事件循环的一部分,由事件循环生成。

  3. V8引擎用于执行我们编写的javascript代码,而libuv是一个库,用于在Node.js中提供多线程功能以执行长时间运行的进程。

  4. 事件循环是单线程的,但Nodejs不是单线程的,因为它在运行时中具有libuv线程池,该线程池负责多线程。

  5. 浏览器API也提供事件循环。

答案 3 :(得分:-1)

V8 项目和 libuv 项目是 NodeJS 最重要的两个依赖项。

我认为在进入 Node 事件循环之前对线程是什么有一个基本的了解很重要。

因此,让我们将线程视为需要由 CPU 执行的指令的待办事项列表,CPU 会从上到下依次运行这些线程。一个进程内部可以有多个线程。

要了解线程,还需要了解一个称为调度的概念,因为您的 CPU 每秒只能处理这么多指令。

现在V8libuv事件循环之间是什么关系?

好吧,V8libuv 我已经建立了 NodeJS 的依赖项,这使得在浏览器之外运行 JavaScript 成为可能。每当我们在计算机上启动 Node 程序时,Node 都会自动启动一个线程并在该线程内执行一些代码。在该单线程内部有一个叫做事件循环的东西,它可以被认为是一个控制结构,它决定了我们的一个线程在任何时间点应该做什么。

它是任何 Node 程序的绝对核心,每个 Node 程序都只有一个事件循环

所以:

<块引用>

事件循环是 libuv 还是 v8 的一部分?

是的,事件循环来自一个由 Node 启动的进程,该进程具有 V8libuv 作为依赖项。

<块引用>

事件队列是事件循环的一部分吗?事件队列是由 libuv 或 v8 引擎生成的还是由事件循环本身生成的?

事件队列,如果我理解这个问题更多地归于您的操作系统调度程序。它决定哪些是最紧急的任务并首先运行它们。

<块引用>

libuv 和 v8 引擎有什么联系?

嗯,它们都是 NodeJS 的依赖项,都是用 C++ 编写的,V8 是 70% C++,libuv 是 100% C++。

<块引用>

如果事件循环是单线程的,libuv 是否可以创建多个线程来处理文件 I/O?

所以这可能会令人困惑,节点事件循环是单线程的,但一些节点标准库模块和一些框架不是单线程的。

libuv 库为 Node 提供了对操作系统的底层访问。 libuv 模块和 C++ 端使用线程池。它可用于运行计算量大的任务。

默认情况下,libuv 在线程池中创建四个线程。除了事件循环中使用的线程之外,还有其他四个线程可用于卸载需要在应用程序内部进行的昂贵计算。

Node 标准库中的许多函数都使用了这个线程池。所以是的 libuv 来创建一个由四个线程组成的线程池。所以 libuv 提供了一个线程池,用于卸载在非常昂贵的函数调用上完成的工作。

<块引用>

浏览器有事件循环机制还是只有 Node.js 有?

我只知道 NodeJS 内部的事件循环机制。

总而言之,我们有一台 2015 年的双核 MacBook Pro。假设您运行两个计算量大的函数,第一个函数在线程池内的第一号线程上运行,它通过 OS 调度程序 并到达第一号 CPU 内核。然后将第二个函数分配给池中的第二个线程,并分配给第二个 CPU 内核。所以线程池发生在 libuv 内部。

有一点很重要,如果您发出 http 请求,libuv 会看到这一点,libuv 和 Node 都没有任何代码来处理所有超级涉及网络请求的低级操作。相反,libuvhttp 请求委托给底层操作系统。

在这种情况下,libuv 用于向操作系统发出请求,并等待操作系统发出对请求返回的响应。因此,因为 libuv 将此委托给您的操作系统,所以由您的操作系统决定是否添加新线程。这是一个 http 请求,我们不受 libuv 的四线程线程池的限制。所有的工作都由操作系统本身完成,我们根本不接触线程池。