进程,你可以把它理解成一个正在运行的程序。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. centos7忘记密码处理办法

    centos7忘记密码处理办法 此界面按e进入grub编辑界面 进入grub编辑界面.把linux16这行的ro修改为rw init=/sysroot/bin/sh. 按ctrl+x进入单用户模式 登 ...

  2. DBLinq (MySQL exactly) Linq To MySql(转)

    Linq to SQL很好用,可惜只支持Microsoft SQL Server 和Microsoft SQL Server Compact Edition,目前比较成熟的免费解决方法是DBLinq( ...

  3. MySql Scaffolding an Existing Database in EF Core

    官方文档详见:https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core-scaffold-exampl ...

  4. linux SVN命令

    1.将文件checkout到本地目录 svn checkout path(path是服务器上的目录)   例如:svn checkout svn://192.168.1.1/pro/domain    ...

  5. 利用 Chrome 原生功能截图网页全图

    打开你想截图的网页了,然后按下 F12(macOS 是 option + command + i)调出开发者工具,接着按「Ctrl + Shift + P」(macOS 是 command + Shi ...

  6. eclipse各版本及下载

    附:Eclipse各个版本简介(http://zh.wikipedia.org/wiki/Eclipse) eclipse下载地址: https://www.eclipse.org/官网--右上角的I ...

  7. 网络之OSI七层协议模型、TCP/IP四层模型

    13.OSI七层模型各层分别有哪些协议及它们的功能 在互联网中实际使用的是TCP/IP参考模型.实际存在的协议主要包括在:物理层.数据链路层.网络层.传输层和应用层.各协议也分别对应这5个层次而已. ...

  8. PP.io的三个阶段,“强中心”——“弱中心”——“去中心”

    什么是PP.io? PP.io是我和Bill发起的存储项目,目的在于为开发者提供一个去中心化的存储和分发平台,能做到更便宜,更高速,更隐私. 当然做去中心化存储的项目也有好几个,FileCoin,Si ...

  9. 支付宝 net

  10. Java笔试面试题整理第二波

    转载至:http://blog.csdn.net/shakespeare001/article/details/51200163 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...