进程,你可以把它理解成一个正在运行的程序。node.js中每个应用程序都是进程类的实例对象。

node.js中有一个 process 全局对象,通过它我们可以获取,运行该程序的用户,环境变量等信息。

一、process 对象

console.log('可执行文件绝对路径', process.execPath);
console.log('版本号', process.version);
console.log('依赖库的版本号', process.versions);
console.log('运行平台', process.platform);
console.log('标准输入流', process.stdin);
console.log('标准输出流', process.stdout);
console.log('标准错误流', process.stderr);
console.log('命令行参数数组', process.argv);
console.log('系统环境变量', process.env);
console.log('进程ID', process.pid);
console.log('标题', process.title);
console.log('处理器架构', process.arch);

通过 memoryUsage() 查看内存使用量:

console.log(process.memoryUsage());

rss 表示进程占用的内存,包括堆,栈,代码段。

heapTotal 表示堆占用的内存。

heapUsed 表示堆使用的部分。

external 表示外部使用的部分,C++对象占用的。

对象,字符串,闭包存放于堆内存,变量存放于栈内存,js源代码存放于代码段。

console.log(process.memoryUsage());
let buf = Buffer.alloc(1024 * 1024 * 1024);
console.log(process.memoryUsage());

当我们通过Buffer创建一个足够大的变量时,这时只能借助于外部内存,使用C++去完成。node.js能够使用的内存上限是1.7G。

使用 chdir() 修改程序当前的工作目录,通过 cwd() 获取当前工作目录。

console.log(process.cwd());
//修改程序当前的工作目录
process.chdir('../');
console.log(process.cwd());

通过 exit() 来结束进程

process.exit(0);

调用 exit() 结束进程时,会触发 'exit' 事件。

process.on('exit', function () {
console.log('程序退出了');
});
process.exit(0);

通过 kill() 给指定进程发送信号

SIGINT 程序终止信号,当用户按下ctrl+c时发出,将通知进程终止。

SIGTERM 程序结束信号,通知程序正常退出,kill()方法默认就是这个信号。

process.kill(process.pid, 'SIGINT');

通过 uptime() 返回程序运行的时间

console.log(process.uptime());

通过 hrtime() 计算代码段运行时间,hrtime() 返回一个数组,第一个表示秒,第二个表示纳秒

let start = process.hrtime();
let sum = 0;
for (i = 0; i < 1000000000; i++) {
sum += i;
}
let end = process.hrtime(start);
console.log('耗时 : ', end[0], '秒');

当程序抛出一个没有被捕获的异常时,触发 'uncaughtException' 事件。

process.on('uncaughtException', function (err) {
console.log('捕获了一个未被处理的异常');
console.log(err);
});
//调用一个未定义的函数
test();

进程接收到一个信号时,会触发信号事件,我们可以监听到该事件。

//让标准输入流处于流动模式,让程序无法退出
process.stdin.resume(); process.on('SIGINT', function () {
console.log('程序退出');
process.exit(0);
}); process.on('SIGTERM', function () {
console.log('程序结束');
});

  

二、子进程模块child_process的使用

我们都知道node.js是单线程的,如果某一个操作需要消耗大量资源和时间,会导致程序整体性能下降。

我们可以创建子进程,让子进程去跑那些费时费力的操作,而主线程该干嘛干嘛。

子进程间可以共享内存,通过互相通信来完成数据的交换。

1、通过 spawn() 创建子进程

const {spawn} = require('child_process');

//参数一表示,要执行的命令
//参数二表示,运行该命令的参数
//参数三表示,创建子进程的配置
let cp1 = spawn('node', ['1.js'], {
//cwd表示当前子进程的工作目录
cwd: process.cwd(),
//子进程的环境变量
env: process.env,
//子进程的标准输入,标准输出,错误,的配置
//pipe表示,父进程与子进程间建立管道,父进程可以访问子进程对应的输入,输出,和错误
//ipc表示,父进程与子进程间建立一个专门用来传递消息的IPC通道,子进程调用send()方法向子进程发送消息,并触发'message'事件
//ignore表示,忽略子进程的标准输入,标准输出,错误。
//inherit表示,子进程共享父进程的标准输入,标准输出,错误。
//stream表示,父进程与子进程共享一个流,比如文件流或socket。
//正整数表示,父进程打开的文件描述符,与子进程共享,比如文件的fd。类似stream流对象共享。
//null或undefined表示,父进程与子进程间创建管道
stdio: ['pipe', process.stdout, 'pipe'],
//子进程是否独立于父进程运行
detached: false
});

1.js的代码:

console.log('hello');

运行代码后,我们可以看到子进程的 'hello',出现在了父进程的标准输出上。因为 stdio 的配置,我们让子进程与父进程共享标准输出。

spawn() 会返回一个子进程对象,我们可以监听该对象的一些事件。

const {spawn} = require('child_process');

let cp1 = spawn('node', ['1.js'], {
cwd: process.cwd(),
env: process.env,
stdio: ['pipe', process.stdout, 'pipe'],
detached: false
}); //子进程所有输入/输出终止时,会触发子进程的 'close' 事件
cp1.on('close', function (code, signal) {
//当父进程关闭子进程时,signal表示父进程发送给子进程的信号名称
console.log('子进程关闭了', code, signal);
}); //子进程退出时,会触发 'exit' 事件
//注意,子进程退出,子进程的输入/输出有可能并未关闭。因为输入/输出有可能多个进程共享。
cp1.on('exit', function (code, signal) {
console.log('子进程退出', code, signal);
}); //子进程出错时,触发
cp1.on('error', function (err) {
console.log(err);
});

注意,stdio 设置成 pipe ,是把子进程的stdin,stdout,stderr导向了 spawn() 返回的子进程对象的stdin,stdout,stderr。

然后父进程就可以通过子进程对象访问stdin,stdout,stderr。

const {spawn} = require('child_process');

let cp1 = spawn('node', ['1.js'], {
cwd: process.cwd(),
env: process.env,
stdio: ['pipe', 'pipe', 'pipe'],
detached: false
}); //监听子进程标准输入,输出,错误的数据。
cp1.stdin.on('data', function (data) {
console.log(data.toString());
});
cp1.stdout.on('data', function (data) {
console.log(data.toString());
});
cp1.stderr.on('data', function (data) {
console.log(data.toString());
});

1.js的代码:

//往子进程标准输出中写入数据
console.log('我是标准输出');
//往子进程错误中写入数据
console.error('我是一个错误');
//往子进程标准输入中写入数据
process.stdin.write('我是标准输入');

当我们设置 stdio 为 ipc 时,会创建一个父进程与子进程传递消息的IPC通道。

const {spawn} = require('child_process');

let cp1 = spawn('node', ['1.js'], {
cwd: process.cwd(),
env: process.env,
//注意这里,子进程只能有一个IPC通道
stdio: ['pipe', 'ipc', 'pipe'],
detached: false
}); //注意这里要用子进程对象进行监听
//监听有没有消息
cp1.on('message', function (data) {
console.log('子进程发送的 : ', data.toString());
}); cp1.send('你好,子进程');

1.js的代码:

process.on('message', function (data) {
console.log('父进程发送的 : ', data.toString());
});
//向父进程发送消息
process.send('你好,父进程');

默认情况下,只有子进程全部退出了,父进程才能退出。我们希望父进程退出了,子进程仍然独立运行。可以通过设置 detached 为 true。

默认情况下,父进程会等待所有子程退出后,才退出。通过使用 unref() 让父进程无需等待子进程就可直接退出。

const {spawn} = require('child_process');
const fs = require('fs');
let fd = fs.openSync('./1.txt', 'w', 0o666); let cp1 = spawn('node', ['1.js'], {
cwd: process.cwd(),
//注意这里,把不需要的设置为ignore,不然主进程仍然会阻塞等待子进程
stdio: ['ignore', fd, 'ignore'],
detached: true
}); cp1.on('error', function (err) {
console.log(err);
}); //解绑子进程,让父进程不用等待子进程
cp1.unref();

1.js的代码:

let i = 0;
let timer = setInterval(function () {
if (i > 20) {
clearInterval(timer);
}
process.stdout.write('写入数据' + i + '\r\n');
i++;
}, 1000);

  

2、通过 fork() 创建子进程

fork() 是 spawn() 的特殊情况,用于创建新的进程,默认建立一个IPC通信通道,允许父进程与子进程进行消息传递。

fork() 返回一个子进程对象,子进程输入/输出操作执行完毕后,父进程不退出,子进程不会自动退出,需调用 exit() 显式退出。

const {fork} = require('child_process');

//参数一表示,运行的模块
//参数二表示,参数列表
//参数三表示,创建子进程的配置
let cp1 = fork('2.js', ['1', '2', '3'], {
//子进程的工作目录
cwd: process.cwd(),
//子进程的环境变量
env: process.env,
//运行模块的可执行文件
execPath: process.execPath,
//传递给可执行文件的参数列表
execArgv: process.execArgv,
//为false表示父进程与子进程共享标准(输入/输出),为true时不共享。
silent: false
}); cp1.on('error', function (err) {
console.log(err);
});

2.js的代码:

for (let i = 0; i < process.argv.length; i++) {
process.stdout.write(process.argv[i] + '\r\n');
}

父进程与子进程间,通过 send() 和 'message'事件来传递消息。

const {fork} = require('child_process');

let cp1 = fork('2.js', [], {
cwd: process.cwd(),
env: process.env,
silent: false
}); //接收消息
cp1.on('message', function (data) {
console.log('父进程收到 : ', JSON.stringify(data));
process.exit(0);
});
//发送消息
cp1.send({name: '你好子进程'});

2.js的代码:

process.on('message', function (data) {
console.log('子进程收到 : ', JSON.stringify(data));
process.send({name: '你好父进程'});
});

  

3、通过exec() 创建子进程

exec() 可以开启一个子进程运行命令,并缓存子进程的输出结果。

const {exec} = require('child_process');

//参数一表示,要运行的命令
//参数二表示,配置选项
//参数三表示,进程终止时的回调
exec('dir', {
//子进程的工作目录
cwd: process.cwd(),
//子进程的环境变量
env: process.env,
//输出的编码
encoding: 'utf8',
//超时时间
timeout: 60 * 1000,
//缓存stdout,stderr最大的字节数
maxBuffer: 1024 * 1024,
//关闭子进程的信号
killSignal: 'SIGTERM'
}, function (err, stdout, stderr) {
console.log(stdout.toString());
});

  

4、通过 execFile() 创建子进程

使用 execFile() 开启一个运行可执行文件的子进程。

const {execFile} = require('child_process');

//参数一表示,可执行文件的名称或路径
//参数二表示,参数列表
//参数三表示,配置选项
//参数四表示,进程终止时的回调
let cp1 = execFile('node', ['3.js', '1', '2', '3'], {
//子进程的工作目录
cwd: process.cwd(),
//子进程的环境变量
env: process.env,
//输出的编码
encoding: 'utf8',
//超时时间
timeout: 60 * 1000,
//缓存stdout,stderr最大的字节数
maxBuffer: 1024 * 1024,
//关闭子进程的信号
killSignal: 'SIGTERM'
}, function (err, stdout, stderr) {
if (err) {
console.log(err);
process.exit();
}
console.log('子进程的输出 : ', stdout.toString());
}); cp1.on('error', function (err) {
console.log(err);
});

3.js的代码:

process.argv.forEach(function (value) {
process.stdout.write(value + '\r\n');
});

  

fork(),exec(),execFile() 都是基于 spawn() 的封装。

node.js中process进程的概念和child_process子进程模块的使用的更多相关文章

  1. Node.js 中的进程和线程

    线程和进程是计算机操作系统的基础概念,在程序员中属于高频词汇,那如何理解呢?Node.js 中的进程和线程又是怎样的呢? 一.进程和线程 1.1.专业性文字定义 进程(Process),进程是计算机中 ...

  2. Node.js中Process.nextTick()和setImmediate()的区别

    一.Webstrom使用node.js IDE的问题 在区别这两个函数之前来说一下Webstrom使用node.js IDE的问题,在配置Node.js的IDE了,但setImmediate().re ...

  3. Node.js 中 process.cwd()与__dirname的区别

    process.cwd() 是当前执行node命令时候的文件夹地址 --工作目录,保证了文件在不同的目录下执行时,路径始终不变 __dirname 是被执行的js 文件的地址 --文件所在目录 当前模 ...

  4. 关于Node.js中的路径问题

    在前端学习过程中,涉及到路径的问题非常多,相对路径,绝对路径等.有时候明明觉得没问题,但是还是会出错.或者说线下没问题,但是到了线上就出现问题,因此弄懂路径问题,非常关键.我们需要知道为什么这个地方既 ...

  5. Node.js中环境变量process.env详解

    Node.js中环境变量process.env详解process | Node.js API 文档http://nodejs.cn/api/process.html官方解释:process 对象是一个 ...

  6. 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick

    [摘要] 官网博文翻译,nodejs中的定时器 示例代码托管在:http://www.github.com/dashnowords/blogs 原文地址:https://nodejs.org/en/d ...

  7. 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick

    目录 Event Loop 是什么? Event Loop 基本解释 事件循环阶段概览 事件循环细节 timers pending callbacks poll阶段 check close callb ...

  8. 在Node.js中使用RabbitMQ系列二 任务队列

    在上一篇文章在Node.js中使用RabbitMQ系列一 Hello world我有使用一个任务队列,不过当时的场景是将消息发送给一个消费者,本篇文章我将讨论有多个消费者的场景. 其实,任务队列最核心 ...

  9. Node.js的process.nextTick(callback)理解

    Node.js是单线程的,基于事件循环,非阻塞 IO的.事件循环中使用一个事件队列,在每个时间点上,系统只会处理一个事件,即使电脑有多个CPU核心,也无法同时并行的处理多个事件.因此,node.js适 ...

随机推荐

  1. because there was insufficient free space available after evicting expired cache entries

    Tomcat运行的时候哗哗哗的报警告 版本是Tomcat 8.5.15 告警信息关键字如下 because there was insufficient free space available af ...

  2. 引入public文件目錄下js/css文件

    <link href="{{ URL::asset('css/ySelect.css') }}" rel="stylesheet" type=" ...

  3. golang垃圾回收和SetFinalizer

    golang自带内存回收机制--GC.GC通过独立的进程执行,它会搜索不再使用的变量,并释放.需要注意的是,进行GC会占用机器资源. GC是自动进行的.如果要手动进行GC,可以调用runtime.GC ...

  4. div遮盖,弹出层

    <html>     <head>     <title>LIGHTBOX EXAMPLE</title>     <meta charset=& ...

  5. 问题 Windows7VMware14安装虚拟机时出现 此主机不支持虚拟化实际模式。需要具备 Intel“VMX 不受限客户机”功能才能在 Intel 处理器上运行此虚拟机。 模块“CPUIDEarly”启动失败。

    问题 Windows7VMware14安装虚拟机时出现 此主机不支持虚拟化实际模式.需要具备 Intel“VMX 不受限客户机”功能才能在 Intel 处理器上运行此虚拟机. 模块“CPUIDEarl ...

  6. VUE打包上线优化

    1.将vue vue-router vuex 尽量使用CDN externals: { 'vue':'Vue', 'vue-router':'VueRouter', 'vuex':'Vuex', 'a ...

  7. Qt配置cmake;运行带参数的程序

    配置cmake编译器,步骤如下: 步骤1:  Qt下新建一个project. 步骤2:  在该project目录下创建一个CMakeLists.txt文件,并按规范编写该文件. Tip: projec ...

  8. 关于SpringMVC

    SpringMVC 原理:1.用户发送请求给服务器.url:user.do2.服务器收到请求.发现DispatchServlet可以处理.于是调用DispatchServlet.3.DispatchS ...

  9. JAVA获取运行程序的src路径

    JavaPrj使用: System.getProperty("user.dir")+"\\src"或直接"\\src"JavaWeb使用Th ...

  10. 分享下自己写的一个微信小程序请求远程数据加载到页面的代码

    1  思路整理 就是页面加载完毕的时候  请求远程接口,然后把数据赋值给页面的变量 ,然后列表循环 2 js相关代码  我是改的 onload函数 /** * 生命周期函数--监听页面加载 */ on ...