likes
comments
collection
share

【悄咪咪学Node.js】7.1 os.cpus()

作者站长头像
站长
· 阅读数 63

OS 模块

1. 前言

本系列课程对非功能性函数内容安排中,将插入一些在生产过程中可能会用到对应函数的例子。

本节课将会引导大家学习了解:

  • os.cpus() 的使用方法
  • os.cpus() 在生产中的作用

学习完本节课程后,应该具有:

  • 使用 os 模块获取 CPU 信息的能力

2. os 模块

2.1 官方解释

os模块提供了与操作系统相关的实用程序方法和属性。可以使用以下命令访问它:

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

参数名参数类型含义
userCPU 在用户模式下花费的毫秒数。
niceCPU 在良好模式下花费的毫秒数。
sysCPU 在系统模式下花费的毫秒数。
idleCPU 在空闲模式下花费的毫秒数。
irqCPU 在中断请求模式下花费的毫秒数。

4 代码例子

const os = require('os');

console.log(os.cpus());

结果

[ { 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 赫兹

再执行以下代码:

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) + '%');

结果

核心总空余时间:128278840 ms
核心总工作时间:18492420 ms
核心总中断请求时间:0 ms
机器持续运行:36692815 ms
核心平均工作时间比:12.60%

初步可判断,机器运行良好,计算压力小,机器持续运行 10 小时 11 分钟 33 秒钟。

5 生产中的作用

通过求得 CPU 核心数来设定子进程数。

假设 childProcess() 函数能生成子进程完成工作:

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 杯。
其中所有人完成自己职位上的工作需要 4 分钟。
剩下的四杯奶茶,恰好有四个员工,其中时间片 4 个,员工 4 个,刚好每人多做一个

结果:
完成所有工作时间为 5 分钟。

奶茶店中有 4 个调制奶茶的员工,老板设立的 4 个职位,每杯奶茶调制时间为 1 分钟,假设有 20 杯奶茶的调制工作:

每个员工负责 1 个职位。
每个职位分到 5 杯。
4 个员工每人完成工作的时间均为 5 分钟。

结果:
完成所有工作时间为 5 分钟。

在这个例子中,员工就是 CPU 核心、职位就是进程。

Tips:根据机器 CPU 核心数制定不同的子进程数才是最高效率的做法,将核心都利用上后,指定更大的进程数并没有意义

5. 小结

本节课程我们主要学习了 如何使用os.cpus()获取 CPU 信息os.cpus() 在生产中的作用

重点如下:

  1. 重点1

    根据 CPU 核心数来制定不同的子进程上限数。

转载自:https://juejin.cn/post/7350586974907940883
评论
请登录