首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nodejs事件循环

Nodejs事件循环
EN

Stack Overflow用户
提问于 2012-05-21 06:46:32
回答 8查看 30.3K关注 0票数 147

nodejs架构内部有两个事件循环吗?

  • libev/libuv
  • v8 javascript事件循环

在I/O请求上,节点是否将请求排队到libeio,而libeio又通过libev通过事件通知数据的可用性,最后这些事件由v8事件循环使用回调来处理?

基本上,libev和libeio是如何在nodejs架构中集成的?

是否有任何文档可以清晰地描述nodejs的内部架构?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2012-06-18 12:02:27

我本人一直在阅读node.js & v8的源代码。

当我试图理解node.js体系结构以编写本机模块时,我遇到了类似的问题,就像您一样。

我在这里发布的是我对node.js的理解,这也可能有点偏离轨道。

  1. 利别夫是事件循环,它实际上在node.js内部运行以执行简单的事件循环操作。它最初是为*nix系统编写的。Libev为运行过程提供了一个简单但优化的事件循环。您可以阅读更多关于libev 这里的内容。
  2. LibEio是一个用于异步执行输入输出的库。它处理文件描述符、数据处理程序、套接字等。您可以在这里阅读更多关于它的这里
  3. LibUv是libeio、libev、c-ares (用于DNS )和iocp (用于windows异步-io)的抽象层。LibUv执行、维护和管理事件池中的所有io和事件。(如属libeio线程池)。您应该查看瑞恩·达尔的教程 on libUv。这将开始让您更好地理解libUv是如何工作的,然后您将了解node.js是如何在libuv和v8之上工作的。

要理解javascript事件循环,您应该考虑观看这些视频。

  • JS会议
  • JSConf2011 (有非常刺激的sfx)
  • 理解事件驱动编程
  • 理解node.js事件循环

要了解libeio如何与node.js一起使用以创建异步模块,您应该看到这个例子

基本上,node.js内部发生的事情是,v8循环在主线程中运行和处理所有javascript部分以及C++模块(根据官方文档,node.js本身是单线程的)。在主线程外部时,libev和libeio在线程池中处理它,libev提供与主循环的交互。因此,据我理解,node.js有一个永久事件循环:那就是v8事件循环。为了处理C++异步任务,它通过libeio & libev使用线程池。

例如:

代码语言:javascript
复制
eio_custom(Task,FLAG,AfterTask,Eio_REQUEST);

它出现在所有模块中,通常是调用线程池中的函数Task。当它完成时,它在主线程中调用AfterTask函数。而Eio_REQUEST是请求处理程序,它可以是一个结构/对象,其目的是提供线程池和主线程之间的通信。

票数 180
EN

Stack Overflow用户

发布于 2016-04-26 08:34:01

看起来像讨论过的一些实体(例如: libev等)已经失去了相关性,因为它已经有一段时间了,但我认为这个问题仍然有很大的潜力。

让我尝试通过一个抽象示例,在Node的上下文中,从今天开始,在抽象UNIX环境中解释事件驱动模型的工作原理。

项目的视角:

  • 脚本引擎开始执行脚本。
  • 每当遇到CPU绑定操作时,都会内联(真正的机器)执行它的完整性。
  • 每当遇到I/O绑定操作时,请求及其完成处理程序都会在“事件机器”(虚拟机)中注册。
  • 以相同的方式重复上述操作,直到脚本结束。CPU绑定操作--在线执行I/O绑定操作,向机器提出上述请求.
  • 当I/O完成时,将调用侦听器。

上面的事件机制称为libuv事件循环框架。节点利用此库实现其事件驱动编程模型。

Node的观点:

  • 有一个线程来承载运行时。
  • 拿起用户脚本。
  • 将其编译成本机杠杆v8
  • 加载二进制文件,然后跳入入口点。
  • 编译后的代码使用编程原语在线执行CPU绑定的活动.
  • 许多与I/O和计时器相关的代码都有本机包装。例如,网络I/O。
  • 因此I/O调用从脚本路由到C++桥,I/O句柄和完成处理程序作为参数传递。
  • 本机代码执行libuv循环。它获取循环,将表示I/O的低级别事件排队,并将本机回调包装器放入libuv循环结构中。
  • 本机代码返回到脚本-目前没有I/O发生!
  • 上面的项目重复多次,直到所有非I/O代码都被执行,所有I/O代码都被注册,libuv才会出现。
  • 最后,当系统中没有任何东西要执行时,节点将控件传递给libuv。
  • libuv开始运行,它收集所有已注册的事件,查询操作系统以获得它们的可操作性。
  • 那些在非阻塞模式下为I/O做好准备的,将被捡起,执行I/O,并发出回调。一个接一个。
  • 那些还没有准备好的(例如,套接字读取,而另一个端点还没有写任何东西)将继续在操作系统中被探测,直到它们可用为止。
  • 循环内部维护一个不断增加的计时器。当应用程序请求延迟回调(如setTimeout)时,会利用这个内部计时器值来计算触发回调的正确时间。

虽然大多数功能都是以这种方式提供的,但一些文件操作(异步版本)是在其他线程的帮助下执行的,这些线程很好地集成到libuv中。虽然网络I/O操作可以等待外部事件,如另一个端点响应数据等,但文件操作需要节点本身的一些工作。例如,如果您打开一个文件并等待fd准备好数据,它将不会发生,因为没有人正在实际读取!同时,如果您从主线程中的文件内联中读取,它可能会阻止程序中的其他活动,并会造成明显的问题,因为与cpu绑定的活动相比,文件操作非常慢。因此,内部工作线程(通过UV_THREADPOOL_SIZE环境变量可配置)用于对文件进行操作,而从程序的角度来看,事件驱动的抽象工作是完整的。

希望这能有所帮助。

票数 23
EN

Stack Overflow用户

发布于 2016-01-02 13:15:04

libuv简介

node.js项目始于2009年,当时JavaScript环境与浏览器脱钩。使用谷歌的V8和马克·莱曼( Marc )的利别夫,node.js将I/O模型--偶发--与一种非常适合编程风格的语言结合在一起,因为它是由浏览器形成的。随着node.js的普及,让它在Windows上运行是很重要的,但是libev只在Unix上运行。Windows等效于内核事件通知机制(如kqueue或(E)轮询)是IOCP。libuv是基于平台的libev或IOCP的抽象,为用户提供了基于libev的API。在节点-v0.9.0版本的libuv 利别夫中。

还有一张图片描述了Node.js中的事件循环(通过@BusyRich )

更新05/09/2017

根据Node.js事件循环医生的说法,

下图显示了事件循环操作顺序的简化概述。

代码语言:javascript
复制
   ┌───────────────────────┐
┌─>│        timers         │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     I/O callbacks     │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     idle, prepare     │
│  └──────────┬────────────┘      ┌───────────────┐
│  ┌──────────┴────────────┐      │   incoming:   │
│  │         poll          │<─────┤  connections, │
│  └──────────┬────────────┘      │   data, etc.  │
│  ┌──────────┴────────────┐      └───────────────┘
│  │        check          │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
└──┤    close callbacks    │
   └───────────────────────┘

注意:每个框将被称为事件循环的“阶段”。

阶段概述

  • timers:此阶段执行setTimeout()setInterval()计划的回调。
  • I/O回调:执行几乎所有回调,但关闭回调除外,定时器调度的回调和setImmediate()除外。
  • 空闲,准备:只在内部使用。
  • 轮询:检索新的I/O事件;节点将在适当的时候阻塞在这里。
  • check:在这里调用setImmediate()回调。
  • 关闭回调:例如socket.on('close', ...)

在事件循环的每次运行之间,Node.js检查它是否在等待任何异步I/O或计时器,如果没有任何异步I/O或定时器,则彻底关闭。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10680601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档