详解Nodejs中的Process对象

news2024/9/23 1:29:22

Nodejs中,process是一个全局对象,它提供了与当前进程和运行时环境交互的方法和属性。通过process对象,我们可以访问进程的信息、控制流程和进行进程间通信,这些都是服务端语言应该具备的能力。本文将全面介绍process对象的使用场景,从基础概念到高级应用,带有代码示例,让您深入了解它的功能与用途。

公众号:Code程序人生,个人网站:https://creatorblog.cn

简单使用

首先,我们来看一些简单的process对象的基础用法。

获取命令行参数

通过process.argv属性可以获取命令行参数,其中argv[0]Nodejs可执行文件的路径,argv[1]是当前执行的脚本文件路径,后续元素是传递给脚本的命令行参数。

// process.js
console.log(process.argv);

执行以下命令:

node process.js arg1 arg2 arg3

输出结果:

结果分析:

[
  'D:\\Nodejs\\node-v16.20.1-win-x86\\node.exe', // Nodejs可执行文件路径
  'D:\\代码\\code-test\\process.js',  // 当前执行的脚本路径
  'arg1', // 命令行参数
  'arg2',
  'arg3'
]

获取环境变量

通过process.env属性可以获取当前进程的环境变量,这在配置不同环境下的应用程序时非常有用。

写入环境变量的方式有很多很多,在前端通常在脚手架里通过cross-env来控制传入环境变量,今天我们写一个最容易演示的,直接在js文件里写入。

// env.js
process.env.NODE_ENV = 'production';
// process.js
require('./env');
console.log(process.env);
console.log(process.env.NODE_ENV);

执行以下命令:

node process.js

输出结果:

image.png

在正式的项目里,咱们可以通过判断环境变量所处的环境,比如开发环境、测试环境、生产环境,来做不同的应对,比如对请求后端接口的前置路径的控制等。

退出进程

通过process.exit()方法可以使进程退出,接收一个可选的退出码参数。

// process.js
console.log("退出前");
process.exit(0);
console.log("退出后"); // 不会执行到这里

执行以下命令:

node process.js

输出结果:

image.png

结果分析:

从结果上来看,在输出 “退出前” 之后,通过process提供的exit方法退出此进程,导致后续并没有输出 “退出后”。

信号处理

通过process.on('SIGINT', callback)方法可以捕获SIGINT信号(通常由Ctrl+C触发),从而实现对进程的优雅退出。

// process.js
process.on('SIGINT', () => {
    console.log("接收到SIGINT信号。正在退出...");
    process.exit(0);
});
console.log("正在等待SIGINT信号...");

setTimeout(() => {

}, 1000000);

因为要复现通过Ctrl + C实现捕获SIGINT信号的方式结束进程,所以我们需要让进程一直运行中,方式有很多,比如起一个web服务等方式,最简单粗暴的,肯定还是使用定时器,给一个很大的延迟秒数,促使此进程不会很快结束,让我们可以手动通过Ctrl + C捕获信号的形式来执行回调函数的内容。

执行以下命令:

node process.js

输出结果:

image.png

通过实际操作,可以复现既定的效果,让我们在进程结束之前通过回调函数做很多需要做的事情

进程间通信

Nodejs中,我们可以通过process对象实现进程间通信,这对于父子进程之间的协作或者多个进程之间的数据传递都很有用。Nodejs提供了child_process模块来实现与子进程的交互。

子进程的创建与通信

通过spawn()方法创建一个子进程,并通过stdinstdoutstderr来进行通信。

// process.js
const { spawn } = require('child_process');

const command = process.platform === 'win32' ? 'cmd.exe' : 'ls';
const args = process.platform === 'win32' ? ['/c', 'dir', '/b'] : ['-l'];

const childProcess = spawn(command, args);

childProcess.stdout.on('data', (data) => {
  console.log(`子进程输出:\n${data}`);
});

childProcess.stderr.on('data', (data) => {
  console.error(`子进程异常:\n${data}`);
});

childProcess.on('close', (code) => {
  console.log(`子进程已退出,返回代码:${code}`);
});

在不同的操作系统和不同的系统位数中,相关处理可能不同,所以我们做了兼容。

执行以下命令:

node process.js

输出结果:

image.png

在上述示例中,我们创建了一个子进程来执行一些输出目录信息的命令,并通过stdoutstderr事件捕获子进程的输出和错误信息。close事件在子进程退出时触发。

父进程与子进程之间的消息传递

除了通过标准输入输出进行通信外,父进程和子进程还可以通过消息传递的方式进行通信,Nodejs提供了fork()方法来创建具有IPC通信的子进程。

// process.js
const { fork } = require('child_process');

const childProcess = fork('./child.js');

childProcess.on('message', (message) => {
  console.log(`父进程收到消息: ${message}`);
});

childProcess.send('Hello,我是父进程!');
// child.js
process.on('message', (message) => {
    console.log(`子进程收到消息: ${message}`);
    process.send('你好,我是子进程!');
});

执行以下命令:

node process.js

输出结果:

image.png

进程信号与事件

Nodejs中的process对象提供了许多事件和信号,用于监听和处理进程相关的状态和事件。

exit事件

exit事件在进程即将退出时触发,可以用来执行一些清理工作。

// process.js
process.on('exit', (code) => {
  console.log(`进程将退出,返回的代码是: ${code}`);
});

console.log("开始!");

执行以下命令:

node process.js

输出结果:

image.png

uncaughtException事件

uncaughtException事件用于捕获未被捕获的异常,但注意它不能替代正常的异常处理,只应该用于记录异常并尽量优雅地退出进程。

// process.js
process.on('uncaughtException', (err) => {
    console.error(`未被捕获的异常: ${err.message}`);
    // 这里可以进行一些异常处理逻辑
});

console.log("开始!");

// 模拟未被捕获的异常
throw new Error("出了问题");
console.log("这里不会被输出");

执行以下命令:

node process.js

输出结果:

image.png

warning事件

warning事件用于捕获一些废弃的API使用或其它可能导致问题的警告信息。

// process.js
process.on('warning', (warning) => {
    console.warn(`警告: ${warning.message}`);
});

// 模拟发出一个废弃API的警告
process.emitWarning("这是不推荐使用的API用法,不推荐使用警告");

执行以下命令:

node process.js

输出结果:

image.png

beforeExit事件

beforeExit事件在进程即将退出之前触发,可以用于执行一些异步操作,但不能阻止进程的退出。

process.on('beforeExit', (code) => {
    console.log(`进程将退出,返回的代码是: ${code}`);
});

console.log("开始!");

// 模拟异步操作
setTimeout(() => {
    console.log("已执行异步操作");
}, 1000);

执行以下命令:

node process.js

输出结果:

image.png

SIGINT信号

SIGINT之前已经介绍过一次了。SIGINT信号通常由Ctrl+C触发,用于请求进程终止。我们可以捕获该信号,并实现优雅地退出进程。

// process.js
process.on('SIGINT', () => {
    console.log("接收到SIGINT信号。正在退出...");
    process.exit(0);
});

console.log("等待SIGINT信号...");

setTimeout(() => {

}, 1000000);

执行以下命令:

node process.js

输出结果:

image.png

SIGHUP、SIGTERM、SIGQUIT信号

除了SIGINT信号,还有一些其他信号可以用于控制进程的行为,例如SIGHUPSIGTERMSIGQUIT等。可以使用类似的方式捕获这些信号并实现相应的处理,这几个信号对于大部分人来说可能不常用,下面我简单叙述一下:

SIGHUP信号

SIGHUP(Hang Up)信号通常在以下情况下发送给进程:

  1. 当终端连接(例如SSH会话)关闭时,与该终端关联的所有进程会收到SIGHUP信号。
  2. 如果操作系统出现某些问题,导致终端会话意外终止,进程也可能收到SIGHUP信号。

默认情况下,对于大多数终端连接,SIGHUP会终止进程。但是,您可以在Nodejs中通过监听process对象的SIGHUP事件来处理这个信号,并在进程终止之前执行一些清理操作。

以下是一个简单的代码示例:

process.on('SIGHUP', () => {
  console.log('收到SIGHUP信号。正在执行清理...');
  // 执行清理操作,如关闭数据库连接、保存数据等
  process.exit(0); // 可以选择退出进程,或执行其他操作
});

SIGTERM信号

SIGTERM信号是由系统管理员或其他进程发送给进程,用于请求进程优雅地终止。SIGTERM通常用于正常关闭进程,允许进程完成正在进行的操作并进行清理,然后自行终止。

Nodejs中,您可以通过监听process对象的SIGTERM事件来处理SIGTERM信号,并在进程终止之前执行清理操作。

以下是一个简单的代码示例:

process.on('SIGTERM', () => {
  console.log('收到SIGTERM信号。正在执行清理...');
  // 执行清理操作,如关闭数据库连接、保存数据等
  process.exit(0); // 可以选择退出进程,或执行其他操作
});

SIGQUIT信号

SIGQUIT信号也是由系统管理员或其他进程发送给进程,用于请求进程终止,但与SIGTERM不同的是,SIGQUIT会产生core dump文件,用于进程调试和故障排除。

Nodejs中,可以通过监听process对象的SIGQUIT事件来处理SIGQUIT信号,并在进程终止之前执行一些清理操作。

以下是一个简单的代码示例:

process.on('SIGQUIT', () => {
  console.log('收到SIGQUIT信号。正在执行清理...');
  // 执行清理操作,如关闭数据库连接、保存数据等
  process.exit(0); // 可以选择退出进程,或执行其他操作
});

请注意,这些信号的处理方式可以根据应用程序的需求进行自定义。对于SIGTERMSIGQUIT信号,您可以在收到信号后执行清理操作,并自行决定是否退出进程。对于SIGHUP信号,默认行为是终止进程,但您可以通过监听SIGHUP信号并处理它来更改这种行为。

进程资源与性能

process对象还提供了一些方法,用于获取当前进程的资源使用情况和性能指标。

获取内存使用情况

// process.js
const used = process.memoryUsage();

console.log(`Memory Usage:`);
console.log(`  - RSS: ${used.rss} bytes`);
console.log(`  - Heap Total: ${used.heapTotal} bytes`);
console.log(`  - Heap Used: ${used.heapUsed} bytes`);
console.log(`  - External: ${used.external} bytes`);

执行以下命令:

node process.js

输出结果:

获取CPU使用情况

// process.js
const startTime = process.hrtime();

setTimeout(() => {
  const endTime = process.hrtime(startTime);
  console.log(`CPU Usage:`);
  console.log(`  - Execution time: ${endTime[0]}s ${endTime[1] / 1000000}ms`);
}, 1000);

执行以下命令:

node process.js

输出结果:

image.png

设置进程标题与优先级

设置进程标题

// process.js

// 设置进程标题
process.title = "My Node.js App";

// 输出进程标题
console.log(process.title);

执行以下命令:

node process.js

输出结果:

image.png

设置进程优先级

Nodejs中,可以使用os模块来设置进程的优先级。具体来说,可以使用os.priority()方法来设置进程的调度优先级。

// process.js
const os = require('os');

// 设置进程的调度优先级为高
os.setPriority(os.constants.priority.PRIORITY_HIGH);

// 获取进程的调度优先级
const priority = os.getPriority();
console.log(`进程优先级: ${priority}`);

执行以下命令:

node process.js

输出结果:

image.png

注意

Nodejs中,os.getPriority()方法返回的数值表示进程的调度优先级。不同的操作系统可能有不同的标准来表示进程优先级,但通常情况下,较小的负数值表示较高的优先级。

Windows系统中,优先级值的范围是 -15 到 15,其中 -15 表示最高优先级,15 表示最低优先级。因此,我在Nodejs中使用os.getPriority()方法返回值为 -14,那么在Windows系统中这个值表示的是接近最高优先级的状态。

需要注意的是,在不同的操作系统上,os.getPriority()方法返回的值可能会有所不同。例如,Linux操作系统上的优先级值范围可能是不同的,具体取决于操作系统的调度策略。

要实现跨平台的代码,最好避免硬编码特定操作系统的优先级值,而是根据需要使用更具有可移植性的方法和方式来设置进程优先级。如果你的应用程序需要使用特定优先级,请确保在不同操作系统上进行适当的测试和调整。

总结

process对象是Nodejs中非常重要的全局对象,提供了许多与进程和运行时环境交互的方法和属性。

在本文中,我们从基础的命令行参数获取和环境变量访问开始,逐步深入到进程间通信、信号处理、进程资源与性能等高级用法。

希望这篇博文能够帮助大家全面了解并灵活应用process对象在Nodejs应用程序开发中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/834430.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【雕爷学编程】 MicroPython动手做(35)——体验小游戏2

知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…

从感知到理解-融合语言模型的多模态大模型研究

©PaperWeekly 原创 作者 | 张燚钧 单位 | 中国移动云能力中心 研究方向 | 预训练大模型 引言 近年来,大语言模型(Large language model, LLM)取得了显著进展。以 ChatGPT 为代表的 LLM 在自然语言任务上展现出惊人的智能涌现能力。尽管…

TPU-NNTC 编译部署LPRNet 车牌识别算法

TPU-NNTC 编译部署LPRNet 车牌识别算法 注意: 由于SOPHGO SE5微服务器的CPU是基于ARM架构,以下步骤将在基于x86架构CPU的开发环境中完成 初始化开发环境(基于x86架构CPU的开发环境中完成)模型转换 (基于x86架构CPU的开发环境中完成) 处理后的LPRNet 项…

sql入门4--函数

字符串函数 # -----字符串函数----- # concat(s1,s2,....)拼接 select concat(Hello ,Mysql); #str转换为小写 select lower(HELLO); # str转换为大写 select upper(mysql); # 向左侧添加 str 位数 要添加的元素 select lpad(1, 3 ,-); # 向右侧添加 str 位数 要添加的元…

【单调栈part01】| 739.每日温度、496.下一个更大元素

🎈LeetCode739. 每日温度 链接:739.每日温度 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不…

rv1109/1126 rknn 模型部署过程

rv1109/1126是瑞芯微出的嵌入式AI芯片,带有npu, 可以用于嵌入式人工智能应用。算法工程师训练出的算法要部署到芯片上,需要经过模型转换和量化,下面记录一下整个过程。 量化环境 模型量化需要安装rk的工具包: rockchip-linux/rk…

weblogic XML反序列化分析——CVE-2017-10271

环境 https://vulhub.org/#/environments/weblogic/CVE-2017-10271/ 启动环境 docker-compose up -d代码审计 传入参数 中间跟进函数 最后的出口 没有限制,直接包参数传入xmlDecoder public String readLine() throws IOException {return (String)this.xml…

Class Central-全球在线课程搜索引擎和学习平台

Class Central(课程中央网站)是一个全球在线课程搜索引擎和学习平台,全球知名的慕课资源导航社区,汇集了来自Coursera(斯坦佛大学)、edX(麻省理工学院)、Futurelearn(英国…

如何使用vue ui创建一个项目?

首先打开cmd 输入vue ui 等待浏览器打开一个窗口,按照下图操作 在"功能页面"中,各个插件代表以下意思: Babel:Babel是一个JavaScript编译器,用于将ES6代码转换为向后兼容的JavaScript版本,以确保…

ORB-SLAM2学习笔记6之D435i双目IR相机运行ROS版ORB-SLAM2并发布位姿pose的rostopic

文章目录 0 引言1 D435i相机配置2 新增发布双目位姿功能2.1 新增d435i_stereo.cc代码2.2 修改CMakeLists.txt2.3 新增配置文件D435i.yaml 3 编译运行和结果3.1 编译运行3.2 结果3.3 可能出现的问题 0 引言 ORB-SLAM2学习笔记1已成功编译安装ROS版本ORB-SLAM2到本地&#xff0c…

C++入门篇6 C++的内存管理

在学习C的内存管理之前,我们先来回顾一下C语言中动态内存 int main() {int* p1 (int*)malloc(sizeof(int));free(p1);// 1.malloc/calloc/realloc的区别是什么?int* p2 (int*)calloc(4, sizeof(int));//calloc 可以初始化空间为0int* p3 (int*)reall…

渗透-01:DNS原理和HTML字符编码-HTML实体编码

一、DNS概念 DNS (Domain Name System 的缩写)就是根据域名查出IP地址(常用) DNS分类&#xff1a; 正向解析&#xff1a;已知域名解析IP反向解析&#xff1a;已知IP解析对应的域名 二、查询过程 工具软件dig可以显示整个查询过程 [rootnode01 ~]# dig baidu.com; <<>&…

pytorch学习——卷积神经网络——以LeNet为例

目录 一.什么是卷积&#xff1f; 二.卷积神经网络的组成 三.卷积网络基本元素介绍 3.1卷积 3.2填充和步幅 3.2.1填充&#xff08;Padding&#xff09; 填充是指在输入数据周围添加额外的边界值&#xff08;通常是零&#xff09;&#xff0c;以扩展输入的尺寸。填充可以在卷…

重磅特性 - SpreadJS推出新插件甘特图,预览版下载体验中

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 甘特图对于业务场景中的工程项目管理、预算执行、生产计划等都能将原有的表格数据&…

【数据分析】numpy (二)

numpy作为数据分析&#xff0c;深度学习常用的库&#xff0c;本篇博客我们来介绍numpy的一些进阶用法&#xff1a; 一&#xff0c;numpy的常用简单内置函数&#xff1a; 1.1求和&#xff1a; a np.array([[1, 2],[3, 4]]) np.sum(a)10 1.2求平均值&#xff1a; np.mean(a…

《向量数据库》——怎么安装向量检索库Faiss?

装 Faiss 以下教程将展示如何在 Linux 系统上安装 Faiss: 1. 安装 Conda。 在安装 Faiss 之前,先在系统上安装 Conda。Conda 是一个开源软件包和环境管理系统,可在 Windows、macOS 和 Linux 操作系统上运行。根据以下步骤在 Linux 系统上安装 Conda。 2. 从官网…

[模拟电路]集成运算放大器

目录 一.前言二.集成运放的介绍及特性分析1.集成运算放大器2.集成运放由四个部分组成3.集成运放的特性 三.集成运放的线性应用&#xff08;引入负反馈&#xff09;1.两个基本运算电路——反相/同相比例运算电路2.同相比例运算电路的特例——电压跟随器3.反相加法运算电路4.同相…

Android组件化入门:一步步搭建组件化架构

1、前言 最近因为业务需求变更&#xff0c;有考虑采用组件化架构进行开发&#xff0c;这方面我之前没有接触过。关于组件化的文章很多&#xff0c;各方大神更是提出了各种的组件化方案&#xff0c;我也看了很多相关文章。但是学习新东西看的再多&#xff0c;不如动手做一次&am…

CAD产品设计逆向软件 FARO RevEng Crack

CAD产品设计逆向软件 FARO RevEng 软件平台能为用户带来全面的数字设计体验。该反向工程软件有助于利用三维点云创建和编辑高质量的网格和 CAD 表面&#xff0c;以实现反向工程工作流程。然后&#xff0c;工业设计师可以利用这些网格模型进行进一步设计或三维打印。 RevEng 的商…

element-ui分页编辑器的使用

代码&#xff1a; 准备好初始数据; total: ,page: {pageSize: 1,pageNumber: 10,}, 当前显示在第一页,每页10条数据。 一,页码改变的事件 handleCurrentChange(val) { this.page.pageSizeval 通过传入(this.page) 获取当前页的数据 } 二.页容量改变 handleSizeChange(val) …