编辑
2023-08-03
Nodejs
00
请注意,本文编写于 203 天前,最后修改于 203 天前,其中某些信息可能已经过时。

目录

简单使用
获取命令行参数
获取环境变量
退出进程
信号处理
进程间通信
子进程的创建与通信
父进程与子进程之间的消息传递
进程信号与事件
exit事件
uncaughtException事件
warning事件
beforeExit事件
SIGINT信号
SIGHUP、SIGTERM、SIGQUIT信号
SIGHUP信号
SIGTERM信号
SIGQUIT信号
进程资源与性能
获取内存使用情况
获取CPU使用情况
设置进程标题与优先级
设置进程标题
设置进程优先级
注意
总结

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

简单使用

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

获取命令行参数

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

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

执行以下命令:

shell
node process.js arg1 arg2 arg3

输出结果:

结果分析:

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

获取环境变量

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

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

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

执行以下命令:

shell
node process.js

输出结果:

image.png

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

退出进程

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

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

执行以下命令:

shell
node process.js

输出结果:

image.png

结果分析:

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

信号处理

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

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

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

执行以下命令:

shell
node process.js

输出结果:

image.png

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

进程间通信

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

子进程的创建与通信

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

js
// 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}`); });

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

执行以下命令:

shell
node process.js

输出结果:

image.png

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

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

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

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

执行以下命令:

shell
node process.js

输出结果:

image.png

进程信号与事件

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

exit事件

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

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

执行以下命令:

shell
node process.js

输出结果:

image.png

uncaughtException事件

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

js
// process.js process.on('uncaughtException', (err) => { console.error(`未被捕获的异常: ${err.message}`); // 这里可以进行一些异常处理逻辑 }); console.log("开始!"); // 模拟未被捕获的异常 throw new Error("出了问题"); console.log("这里不会被输出");

执行以下命令:

shell
node process.js

输出结果:

image.png

warning事件

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

js
// process.js process.on('warning', (warning) => { console.warn(`警告: ${warning.message}`); }); // 模拟发出一个废弃API的警告 process.emitWarning("这是不推荐使用的API用法,不推荐使用警告");

执行以下命令:

shell
node process.js

输出结果:

image.png

beforeExit事件

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

js
process.on('beforeExit', (code) => { console.log(`进程将退出,返回的代码是: ${code}`); }); console.log("开始!"); // 模拟异步操作 setTimeout(() => { console.log("已执行异步操作"); }, 1000);

执行以下命令:

shell
node process.js

输出结果:

image.png

SIGINT信号

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

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

执行以下命令:

shell
node process.js

输出结果:

image.png

SIGHUP、SIGTERM、SIGQUIT信号

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

SIGHUP信号

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

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

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

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

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

SIGTERM信号

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

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

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

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

SIGQUIT信号

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

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

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

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

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

进程资源与性能

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

获取内存使用情况

js
// 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`);

执行以下命令:

shell
node process.js

输出结果:

获取CPU使用情况

js
// 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);

执行以下命令:

shell
node process.js

输出结果:

image.png

设置进程标题与优先级

设置进程标题

js
// process.js // 设置进程标题 process.title = "My Node.js App"; // 输出进程标题 console.log(process.title);

执行以下命令:

shell
node process.js

输出结果:

image.png

设置进程优先级

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

js
// process.js const os = require('os'); // 设置进程的调度优先级为高 os.setPriority(os.constants.priority.PRIORITY_HIGH); // 获取进程的调度优先级 const priority = os.getPriority(); console.log(`进程优先级: ${priority}`);

执行以下命令:

shell
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应用程序开发中。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:CreatorRay

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!