Nodejs事件循环

Nodejs事件循环

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

  • libev / libuv

  • v8 javascript事件循环

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

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

有没有可用于提供nodejs内部架构清晰图片的文档?


凤凰求蛊
浏览 735回答 3
3回答

喵喵时光机

看起来所讨论的一些实体(例如:libev等)已经失去了相关性,因为它已经有一段时间了,但我认为这个问题仍然具有很大的潜力。让我尝试在抽象的UNIX环境中,在Node的上下文中,借助抽象示例来解释事件驱动模型的工作。计划的观点:脚本引擎开始执行脚本。每当遇到CPU绑定操作时,它都会在内联(真实机器)中完成。每当遇到I / O绑定操作时,请求及其完成处理程序都会在“事件机器”(虚拟机)中注册以相同的方式重复操作,直到脚本结束。CPU绑定操作 - 执行内联,I / O绑定操作,如上所述向机器请求。当I / O完成时,将回调一下监听器。上面的事件机制称为libuv AKA事件循环框架。Node利用此库来实现其事件驱动的编程模型。Node的观点:有一个线程来托管运行时。拿起用户脚本。将其编译为本机[杠杆v8]加载二进制文件,然后跳转到入口点。已编译的代码使用编程原语在线执行CPU绑定活动。许多I / O和计时器相关的代码都有本机包装。例如,网络I / O.因此,I / O调用从脚本路由到C ++桥接器,I / O句柄和完成处理程序作为参数传递。本机代码执行libuv循环。它获取循环,将表示I / O的低级事件排入队列,并将本机回调包装器排入libuv循环结构。本机代码返回到脚本 - 此刻不会发生I / O!上面的项目重复多次,直到执行所有非I / O代码,并且所有I / O代码都被注册到libuv。最后,当系统中没有任何内容要执行时,节点将控制权传递给libuvlibuv开始行动,它获取所有已注册的事件,查询操作系统以获得其可操作性。在非阻塞模式下准备好I / O的那些被拾取,执行I / O,并且发出它们的回调。一个接一个地。尚未准备好的那些(例如套接字读取,另一个端点尚未写入任何内容)将继续用OS进行探测,直到它们可用。循环内部维持一个不断增加的计时器。当应用程序请求延迟回调(例如setTimeout)时,将利用此内部计时器值来计算触发回调的正确时间。虽然大多数功能都以这种方式迎合,但文件操作的一些(异步版本)是在附加线程的帮助下执行的,并且很好地集成到libuv中。虽然网络I / O操作可以等待期望外部事件,例如另一个端点响应数据等,但文件操作需要来自节点本身的一些工作。例如,如果你打开一个文件并等待fd准备好数据,它就不会发生,因为没有人正在阅读!同时,如果您从主线程中的内联文件中读取,它可能会阻止程序中的其他活动,并且可能会产生可见问题,因为与cpu绑定活动相比,文件操作非常慢。因此,内部工作线程(可通过UV_THREADPOOL_SIZE环境变量配置)用于对文件进行操作,希望这可以帮助。

眼眸繁星

ibuv简介该Node.js的项目开始于2009年从浏览器分离一个JavaScript环境。使用谷歌的V8和Marc Lehmann的libev,node.js将I / O模型 - 偶数 - 与一种非常适合编程风格的语言相结合; 由于浏览器的形成方式。随着node.js越来越流行,让它在Windows上运行很重要,但libev只能在Unix上运行。Windows等效的内核事件通知机制(如kqueue或(e)轮询)是IOCP。libuv是一个围绕libev或IOCP的抽象,取决于平台,为用户提供基于libev的API。在node-v0.9.0版本的libuv中,libev被删除了。还有一张用@ BusyRich描述Node.js中的事件循环的图片根据这个doc Node.js事件循环,下图显示了事件循环操作顺序的简要概述。&nbsp; &nbsp;┌───────────────────────┐┌─>│&nbsp; &nbsp; &nbsp; &nbsp; timers&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;││&nbsp; └──────────┬────────────┘│&nbsp; ┌──────────┴────────────┐│&nbsp; │&nbsp; &nbsp; &nbsp;I/O callbacks&nbsp; &nbsp; &nbsp;││&nbsp; └──────────┬────────────┘│&nbsp; ┌──────────┴────────────┐│&nbsp; │&nbsp; &nbsp; &nbsp;idle, prepare&nbsp; &nbsp; &nbsp;││&nbsp; └──────────┬────────────┘&nbsp; &nbsp; &nbsp; ┌───────────────┐│&nbsp; ┌──────────┴────────────┐&nbsp; &nbsp; &nbsp; │&nbsp; &nbsp;incoming:&nbsp; &nbsp;││&nbsp; │&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;poll&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │<─────┤&nbsp; connections, ││&nbsp; └──────────┬────────────┘&nbsp; &nbsp; &nbsp; │&nbsp; &nbsp;data, etc.&nbsp; ││&nbsp; ┌──────────┴────────────┐&nbsp; &nbsp; &nbsp; └───────────────┘│&nbsp; │&nbsp; &nbsp; &nbsp; &nbsp; check&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ││&nbsp; └──────────┬────────────┘│&nbsp; ┌──────────┴────────────┐└──┤&nbsp; &nbsp; close callbacks&nbsp; &nbsp; │&nbsp; &nbsp;└───────────────────────┘注意:每个框将被称为事件循环的“阶段”。阶段概述定时器:此阶段执行由setTimeout()和调度的回调setInterval()。I / O回调:除了执行几乎所有回调之外关闭回调,由计时器安排的回调,和setImmediate()。空闲,准备:仅在内部使用。poll:检索新的I / O事件; 节点将在适当时阻止此处。check:setImmediate()在这里调用回调。关闭回调:例如socket.on('close', ...)。在事件循环的每次运行之间,Node.js检查它是否在等待任何异步I / O或定时器,如果没有,则检查是否干净。
打开App,查看更多内容
随时随地看视频慕课网APP