Nodejs 第七十一章(libuv)

2024-05-15 09:20
文章标签 nodejs libuv 第七十一

本文主要是介绍Nodejs 第七十一章(libuv),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

libuv

在Node.js中,libuv是作为其事件循环和异步I/O的核心组件而存在的。Node.js是构建在libuv之上的,它利用libuv来处理底层的异步操作,如文件I/O、网络通信和定时器等。

libuv在Node.js中扮演了以下几个重要角色:

  1. 事件循环(Event Loop):libuv实现了Node.js的事件循环机制,负责管理事件的调度和执行。事件循环是Node.js的核心机制,它使得Node.js能够以非阻塞的方式处理大量并发操作。
  2. 异步I/O操作:libuv提供了一组异步I/O的API,用于处理文件、网络和其他I/O操作。这些API能够在后台进行操作,而无需阻塞主线程,从而实现高效的并发处理。
  3. 网络通信:libuv封装了底层的网络通信功能,包括TCP和UDP套接字的创建、绑定、监听和连接等操作。它提供了高级的网络接口,方便开发者构建基于网络的应用程序。
  4. 定时器和事件触发:libuv提供了定时器相关的API,可以创建和管理定时器,以及在指定时间间隔后触发相应的回调函数。这对于处理定时任务和调度是非常有用的。
  5. 跨平台支持:libuv实现了对不同操作系统的抽象封装,使得Node.js能够在不同的平台上运行,并保持一致的行为和性能。

事件循环

nodejs官网事件循环描述

在Nodejs中,事件循环分为6个阶段。每个阶段都有一个任务队列。当Node启动时,会创建一个事件循环线程,并依次按照下图所示顺序进入每个阶段,执行每个阶段的回调

Nodejs事件循环可以划分为两种,微任务和宏任务

宏任务

  1. timers 执行setTimeout和setInterval的回调
  2. pending callbacks 执行推迟的回调如IO,计时器
  3. idle,prepare 空闲状态 nodejs内部使用无需关心
  4. poll 执行与I/O相关的回调(除了关闭回调、计时器调度的回调和setImmediate之外,几乎所有回调都执行) 例如 fs的回调 http回调
  5. check 执行setImmediate的回调
  6. close callback 执行例如socket.on('close', ...) 关闭的回调

微任务

  1. process.nextTick
  2. promise
注意事项 不准确计时器

我们根据上方顺序编写一个案例 输出3 1 2,并不是 1 2 3

官网解释过这个原因,是因为,在事件循环的每个循环迭代中,libuv会调用uv__update_time函数来更新当前的时间戳。这个时间戳通常用于计算定时器的超时时间和检查事件的发生时间,而 setImmediate,则是把回调函数直接插入队列,所以执行效率比较高。所以就会造成顺序不稳定的一个原因

剖析源码

libuv/src/unix/core.c

int uv_run(uv_loop_t* loop, uv_run_mode mode) {int timeout;int r;int can_sleep;r = uv__loop_alive(loop); //检查事件循环是否活跃if (!r) //如果事件循环不活跃,直接返回uv__update_time(loop); //调用这个函数更新时间戳去检查计时器 超时时间 耗时/* Maintain backwards compatibility by processing timers before entering the* while loop for UV_RUN_DEFAULT. Otherwise timers only need to be executed* once, which should be done after polling in order to maintain proper* execution order of the conceptual event loop. */if (mode == UV_RUN_DEFAULT && r != 0 && loop->stop_flag == 0) {uv__update_time(loop); //更新时间uv__run_timers(loop); //执行定时器}while (r != 0 && loop->stop_flag == 0) {can_sleep =uv__queue_empty(&loop->pending_queue) &&uv__queue_empty(&loop->idle_handles);uv__run_pending(loop); //执行事件队列中的事件uv__run_idle(loop); //执行空闲队列中的事件uv__run_prepare(loop); //执行预备队列中的事件timeout = 0;if ((mode == UV_RUN_ONCE && can_sleep) || mode == UV_RUN_DEFAULT)timeout = uv__backend_timeout(loop);uv__metrics_inc_loop_count(loop);uv__io_poll(loop, timeout); //执行事件循环/* Process immediate callbacks (e.g. write_cb) a small fixed number of* times to avoid loop starvation.*/for (r = 0; r < 8 && !uv__queue_empty(&loop->pending_queue); r++)uv__run_pending(loop);/* Run one final update on the provider_idle_time in case uv__io_poll* returned because the timeout expired, but no events were received. This* call will be ignored if the provider_entry_time was either never set (if* the timeout == 0) or was already updated b/c an event was received.*/uv__metrics_update_idle_time(loop); //更新空闲时间uv__run_check(loop); //执行检查队列中的事件 setImmediateuv__run_closing_handles(loop); //执行关闭队列中的事件uv__update_time(loop); //更新时间uv__run_timers(loop); //执行定时器r = uv__loop_alive(loop);if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)break;}

libuv/src/unix/internal.c

uv__update_time函数实现

UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {/* Use a fast time source if available.  We only need millisecond precision.*/// 这个函数通过调用 `gethrtime` 获取系统当前时间,精度非常高,单位是纳秒(ns),// 1 纳秒等于十亿分之一秒。除 `1000000` 后的时间单位为 毫秒(ms)loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000;
}

注意事项 微任务

在nodejs不同版本微任务执行策略不同

低版本 nextTick 优先于 Promise

nodejs V10 测试

nodejs V20测试

这篇关于Nodejs 第七十一章(libuv)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991435

相关文章

安装nodejs环境

本文介绍了如何通过nvm(NodeVersionManager)安装和管理Node.js及npm的不同版本,包括下载安装脚本、检查版本并安装特定版本的方法。 1、安装nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash 2、查看nvm版本 nvm --version 3、安装

nvm及nodejs安装相关

安装 1.清空文件夹,卸载nvm及nodejs 2.下载安装包 https://github.com/coreybutler/nvm-windows/releases (也下载有) 3.安装nvm 地址写D:/nvm和D:/nodejs 4.安装nodejs nvm ls available //查询版本nvm install 16.20.2 //安装对应版本号nvm use 1

Nodejs的Express框架使用总结

初始安装express,你也可以通过编辑器的shell安装依赖,比如vs # 创建并切换到 myapp 目录mkdir myappcd myapp# 初始化 package.json 文件npm init -y# 安装 express 到项目中npm i express 新建一个基础的接口 // 0. 加载 Expressconst express = require('expre

YApi 接口管理开源工具 nodejs+ mongoDB

前言介绍 Yapi 由 YMFE 开源,旨在为开发、产品、测试人员提供更优雅的接口管理服务,可以帮助开发者轻松创建、发布、维护 API。 权限管理 YApi 成熟的团队管理扁平化项目权限配置满足各类企业的需求 可视化接口管理 基于 websocket 的多人协作接口编辑功能和类 postman 测试工具,让多人协作成倍提升开发效率 Mock Server 易用的 Mock Server,

linux 安装 nodejs

1、去官网下载和自己系统匹配的文件:  英文网址:https://nodejs.org/en/download/  中文网址:http://nodejs.cn/download/  通过  uname -a  命令查看到我的Linux系统位数是64位(备注:x86_64表示64位系统, i686 i386表示32位系统),如图 故下载一下红色框中文件 ,版本为v6.10.0 2、

【NodeJS】Error: Cannot find module 'ms'

转载自:http://blog.csdn.net/echo_ae/article/details/75097004 问题: Error: Cannot find module 'ms'at Function.Module._resolveFilename (module.js:469:15)at Function.Module._load (module.js:417:25)at Module

【NodeJS】如何安装淘宝cnpm

工具官网 Node.js淘宝 NPM 镜像 安装cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org 输入cnpm -v查看是否正常(前提是你已经设置好了环境变量) cnpm -v 如果想给npm添加淘宝镜像,请参考: 【NodeJS】修改npm的registry为淘宝镜像(npm.taobao.o

【NodeJS】Unexpected token (109:0) 返回错误码500

刚开始报错是这样的: Unexpected token call 是什么我没看懂,但我发现 span.label.lable-success 后面的 #[i+1] 写错了,应该是 #{i+1} 改成完这个错误后又是一个错误提示: What? Unexpected token (109:0) 返回错误码500是什么鬼 我先将自己这段源码的 - if ... - else 检查下

怎么利用NodeJS发送视频短信

随着5G时代的来临,企业的数字化转型步伐日益加快,视频短信作为新兴的数字营销工具,正逐步展现出其大的潜力。视频群发短信以其独特的形式和内容,将图片、文字、视频、声音融为一体,为用户带来全新的直观感受,为企业营销注入新的活力。 支持免费对接试用乐讯通PaaS平台 找好用的短信平台,选择乐讯通,短信群发|短信平台|群发短信软件|群发短信平台|乐讯通PaaS平台http://yun.loktong

Nodejs 串口通信 : websocket , serialport

最近在学习如何实现web页面和串口间通信,网页请求使用websocket,实现的基本功能如下: 1、基本需求:硬件:有两个信号灯(TLA-505-1T),一个485继电器(开关),电压转换器,工业触屏一体机。 2、原理图:                  3工作原理: 首先一体机中采用node开发服务器,网页请求采用websocket协议,直接放代码了: var express