我正在学习Node.js的架构,以下是我的问题:
- 事件循环是libuv还是v8的一部分?
- 事件队列是事件循环的一部分吗?事件队列由libuv或v8引擎产生,还是由事件循环本身产生?
- libuv和v8引擎之间有什么关系?
- 如果事件循环是单线程的,那么libuv会创建多个线程来处理文件I/O吗?
- 浏览器是否具有事件循环机制,还是仅限于Node.js?
我正在学习Node.js的架构,以下是我的问题:
事件循环首先是JavaScript编程模型的重要概念。实际上,几乎所有V8嵌入式引擎都需要实现事件循环。V8提供了一个默认实现,可以由嵌入者替换或扩展。
我不理解这个问题。(我猜答案是“是”,但“事件循环”和“事件队列”的区别是什么?)
没有。(除了Node.js同时使用两者。)
是的,事件循环是单线程的。
是的,浏览器也有一个事件循环(见问题1)。
PumpMessageLoop
:https://cs.chromium.org/chromium/src/v8/src/libplatform/default-platform.cc?g=0&l=130 - jmrk是的,Event Loop 来自由 Node 启动的进程,并具有 V8 和 libuv 作为依赖项。Event Loop 是 libuv 还是 V8 的一部分?
如果我理解问题正确,那么事件队列更多地受到操作系统调度程序的限制,调度程序决定哪些任务最紧急并首先运行它们。事件队列是否是事件循环的一部分?事件队列是否由 libuv 或 v8 引擎或事件循环本身生成?
嗯,它们都是 NodeJS 的依赖项,都是用 C++ 编写的,V8 是 70% 的 C++,而 libuv 是 100% 的 C++。libuv 和 v8 引擎之间的联系是什么?
这可能令人困惑,Node 的事件循环是单线程的,但是一些 Node 标准库模块和某些框架不是单线程的。 libuv 库使 Node 具有底层访问操作系统的能力。该模块和 C++ 部分利用线程池运行计算密集型任务。如果事件循环是单线程的,那么 libuv 是否会创建多个线程来处理文件 I/O?
浏览器是否具有事件循环机制,只有 Node.js 才有吗?
</blockquote>我只知道 NodeJS 中存在事件循环机制。
总之,我们拥有一台双核的 2015 MacBook Pro。假设运行两个计算密集型函数,第一个函数在线程池内的第一个线程上运行,通过OS Scheduler并分配给 CPU 核心号码一。然后第二个函数被分配到池中的第二个线程,并分配到第二个 CPU 核心。因此,该线程池发生在libuv内部。http
请求,则libuv 会注意到并且 Node 没有任何代码来处理涉及网络请求的所有超低级别操作。相反,libuv 将 http
请求委托给底层操作系统。http
请求,在此我们不限于使用libuv的四个线程线程池。所有工作都由操作系统自己完成,我们根本没有触及线程池。实际上,这并不像被选为答案的帖子所述那样简单。我希望我的评论能更加准确。希望我正确理解了Sam Roberts(IBM)在有关Node事件循环的讲话中的观点。
您可以在此处查看演讲:https://www.youtube.com/watch?v=P9csgxBgaZ8
这是对@jmrk给出的答案的补充。
Libuv将任务委托给底层操作系统。然后,操作系统负责在您监听的事件发生时发送通知。它会执行Node中许多操作,例如:套接字(net/dgram/http/tls/https/child_process pipes、stdin、out、err)、超时和间隔等。
但是,并非所有事情都可以像这样委托给底层操作系统。有时需要创建线程(默认情况下有4个线程,但您可以使用UV_THREADPOOL_SIZE更改此设置)。不可轮询的操作包括文件系统操作、dns.lookup()和某些加密函数。
请仔细阅读以下内容:
V8引擎是火车教练的引擎。它有一定的职责,包括提供事件循环以运行异步任务。
事件循环是执行异步任务的核心。当C++ Web API完成一个函数(任务)时,回调被调用。它被移动到事件队列中,并等待堆栈变为空。因此,事件队列是事件循环的一部分,并由事件循环生成。
V8引擎用于执行我们编写的JavaScript代码,而libuv是一个库,用于在Node.js中提供多线程功能以执行长时间运行的进程。
事件循环是单线程的,但Node.js不是单线程的,因为它在其运行时具有libuv线程池,负责多线程。
浏览器API也提供事件循环。