OS 模块
1. 前言
本系列课程对非功能性函数内容安排中,将插入一些在生产过程中可能会用到对应函数的例子。
本节课将会引导大家学习了解:
os.cpus()
的使用方法os.cpus()
在生产中的作用
学习完本节课程后,应该具有:
- 使用
os
模块获取 CPU 信息的能力
2. os 模块
2.1 官方解释
os模块提供了与操作系统相关的实用程序方法和属性。可以使用以下命令访问它:
js
const os = require('os');
2.2 笔者解释
os模块还能提供一些硬件信息,例如本节课程将会提及的 os.cpus()
函数。
3 os.cpus()
os.cpus()
可以获取一些 CPU 的参数。
3.1 参数列表
os.cpus()
参数名 | 参数类型 | 含义 |
---|---|---|
model | 对应内核的型号 | |
speed | 以兆赫兹为单位 | |
times | 不同模式下所用时间 |
os.cpus().times
参数名 | 参数类型 | 含义 |
---|---|---|
user | CPU 在用户模式下花费的毫秒数。 | |
nice | CPU 在良好模式下花费的毫秒数。 | |
sys | CPU 在系统模式下花费的毫秒数。 | |
idle | CPU 在空闲模式下花费的毫秒数。 | |
irq | CPU 在中断请求模式下花费的毫秒数。 |
4 代码例子
js
const os = require('os');
console.log(os.cpus());
结果
shell
[ { model: 'Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz',
speed: 3100,
times:
{ user: 4445480, nice: 0, sys: 3350020, idle: 28158660, irq: 0 } },
{ model: 'Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz',
speed: 3100,
times:
{ user: 1088550, nice: 0, sys: 981290, idle: 33883060, irq: 0 } },
{ model: 'Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz',
speed: 3100,
times:
{ user: 3639780, nice: 0, sys: 2981220, idle: 29331900, irq: 0 } },
{ model: 'Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz',
speed: 3100,
times:
{ user: 775880, nice: 0, sys: 662640, idle: 34514380, irq: 0 } } ]
能获得以下信息:
- 我的电脑是 4 核
- 所有 CPU 的型号都是 Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz
- 所有 CPU 的速度都是 3.1G 赫兹
再执行以下代码:
js
const os = require('os');
let sum_idle = 0,
sum_irq = 0,
sum_busy = 0;
os.cpus().forEach(function(cpu) {
sum_idle += cpu.times.idle; // 累加空闲时间
sum_irq += cpu.times.irq; // 累加中断请求时间
sum_busy += cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.irq; // 累加工作时间
});
console.log('核心总空余时间:' + sum_idle + ' ms');
console.log('核心总工作时间:' + sum_busy + ' ms');
console.log('核心总中断请求时间:' + sum_irq + ' ms');
console.log('机器持续运行:' + ((sum_idle + sum_busy) / os.cpus().length) + ' ms');
console.log('核心平均工作时间比:' + parseFloat((sum_busy / (sum_idle + sum_busy)) * 100).toFixed(2) + '%');
结果
shell
核心总空余时间:128278840 ms
核心总工作时间:18492420 ms
核心总中断请求时间:0 ms
机器持续运行:36692815 ms
核心平均工作时间比:12.60%
初步可判断,机器运行良好,计算压力小,机器持续运行 10 小时 11 分钟 33 秒钟。
5 生产中的作用
通过求得 CPU 核心数来设定子进程数。
假设 childProcess()
函数能生成子进程完成工作:
js
function childProcess() {
// todo...
// 具体实现规则请参考 child_process 章节
}
// 根据 CPU 核心数生成子进程
for (let i = 0; i < os.cpus().length; i++) {
childProcess();
}
这么使用是有深层次的原因的:
- 一个 Node.js 进程只会使用一个 CPU 核心
- 不同 CPU 核心之间的负载会自动调节
- 一个 CPU 核心同一时间只能执行一条机器指令
以上述例子中电脑的数据为例,启动 Node.js 进程的时候,最多只会用到机器的 1/4 运算能力,因为 一个 Node.js 进程只会使用一个 CPU 核心。但启用子进程后,如果其他 CPU 核心的负载低,那么就会将子进程分配给另外的 CPU,从而高效利用机器性能。
那么是开的子进程越多,效率越高吗?
答案是 ------ 不是的!
假设开了五个 Node.js 进程,在上述机器中,必定有一个 CPU 核心是负责两个 Node.js 进程的,这是因为 一个 CPU 核心同一时间只能执行一条机器指令。
打个生活化的比喻:
奶茶店中有 4 个调制奶茶的员工,而老板却设立的 5 个职位,每杯奶茶调制时间为 1 分钟,假设有 20 杯奶茶的调制工作:
这必定会使其中 1 个员工负责 2 个职位的工作。
每个职位分到 4 杯。
其中负责 2 个职位的人需要 8 分钟才能完成工作,其余人需要 4 分钟。
结果:
完成所有工作时间为 8 分钟。
奶茶店中有 4 个调制奶茶的员工,老板设立的 4 个职位,每杯奶茶调制时间为 1 分钟,假设有 20 杯奶茶的调制工作:
每个员工负责 1 个职位。
每个职位分到 5 杯。
4 个员工每人完成工作的时间均为 5 分钟。
结果:
完成所有工作时间为 5 分钟。
在这个例子中,员工就是 CPU 核心、职位就是进程。
Tips:根据机器 CPU 核心数制定不同的子进程数才是最高效率的做法。
5. 小结
本节课程我们主要学习了 如何使用os.cpus()
获取 CPU 信息 、os.cpus()
在生产中的作用。
重点如下:
-
重点1
根据 CPU 核心数来制定不同的子进程上限数。