详细分析Node.js 多进程


Posted in Javascript onJune 22, 2020

我们都知道 Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。

每个子进程总是带有三个流对象:child.stdin, child.stdout 和child.stderr。他们可能会共享父进程的 stdio 流,或者也可以是独立的被导流的流对象。

Node 提供了 child_process 模块来创建子进程,方法有:

  • exec - child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。
  • spawn - child_process.spawn 使用指定的命令行参数创建新进程。
  • fork - child_process.fork 是 spawn()的特殊形式,用于在子进程中运行的模块,如 fork('./son.js') 相当于 spawn('node', ['./son.js']) 。与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。

exec() 方法

child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。

语法如下所示:

child_process.exec(command[, options], callback)

参数

参数说明如下:

command: 字符串, 将要运行的命令,参数使用空格隔开

options :对象,可以是:

  • cwd ,字符串,子进程的当前工作目录
  • env,对象 环境变量键值对
  • encoding ,字符串,字符编码(默认: 'utf8')
  • shell ,字符串,将要执行命令的 Shell(默认: 在 UNIX 中为/bin/sh, 在 Windows 中为cmd.exe, Shell 应当能识别 -c开关在 UNIX 中,或 /s /c 在 Windows 中。 在Windows 中,命令行解析应当能兼容cmd.exe)
  • timeout,数字,超时时间(默认: 0)
  • maxBuffer,数字, 在 stdout 或 stderr 中允许存在的最大缓冲(二进制),如果超出那么子进程将会被杀死 (默认: 200*1024)
  • killSignal ,字符串,结束信号(默认:'SIGTERM')
  • uid,数字,设置用户进程的 ID
  • gid,数字,设置进程组的 ID

callback :回调函数,包含三个参数error, stdout 和 stderr。

exec() 方法返回最大的缓冲区,并等待进程结束,一次性返回缓冲区的内容。

实例

让我们创建两个 js 文件 support.js 和 master.js。

support.js 文件代码:

console.log("进程 " + process.argv[2] + " 执行。" );

master.js 文件代码:

const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
  var workerProcess = child_process.exec('node support.js '+i, function (error, stdout, stderr) {
    if (error) {
      console.log(error.stack);
      console.log('Error code: '+error.code);
      console.log('Signal received: '+error.signal);
    }
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
  });
 
  workerProcess.on('exit', function (code) {
    console.log('子进程已退出,退出码 '+code);
  });
}

执行以上代码,输出结果为:

$ node master.js
子进程已退出,退出码 0
stdout: 进程 1 执行。

stderr:
子进程已退出,退出码 0
stdout: 进程 0 执行。

stderr:
子进程已退出,退出码 0
stdout: 进程 2 执行。

stderr:

spawn() 方法

child_process.spawn 使用指定的命令行参数创建新进程,语法格式如下:

child_process.spawn(command[, args][, options])

参数

参数说明如下:

command: 将要运行的命令

args: Array 字符串参数数组

options Object

  • cwd String 子进程的当前工作目录
  • env Object 环境变量键值对
  • stdio Array|String 子进程的 stdio 配置
  • detached Boolean 这个子进程将会变成进程组的领导
  • uid Number 设置用户进程的 ID
  • gid Number 设置进程组的 ID

spawn() 方法返回流 (stdout & stderr),在进程返回大量数据时使用。进程一旦开始执行时 spawn() 就开始接收响应。

实例

让我们创建两个 js 文件 support.js 和 master.js。

support.js 文件代码:

console.log("进程 " + process.argv[2] + " 执行。" );

master.js 文件代码:

const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
  var workerProcess = child_process.spawn('node', ['support.js', i]);
 
  workerProcess.stdout.on('data', function (data) {
   console.log('stdout: ' + data);
  });
 
  workerProcess.stderr.on('data', function (data) {
   console.log('stderr: ' + data);
  });
 
  workerProcess.on('close', function (code) {
   console.log('子进程已退出,退出码 '+code);
  });
}

执行以上代码,输出结果为:

$ node master.js stdout: 进程 0 执行。

子进程已退出,退出码 0
stdout: 进程 1 执行。

子进程已退出,退出码 0
stdout: 进程 2 执行。

子进程已退出,退出码 0

fork 方法

child_process.fork 是 spawn() 方法的特殊形式,用于创建进程,语法格式如下:

child_process.fork(modulePath[, args][, options])

参数

参数说明如下:

modulePath: String,将要在子进程中运行的模块

args: Array 字符串参数数组

options:Object

  • cwd String 子进程的当前工作目录
  • env Object 环境变量键值对
  • execPath String 创建子进程的可执行文件
  • execArgv Array 子进程的可执行文件的字符串参数数组(默认: process.execArgv)
  • silent Boolean 如果为true,子进程的stdin,stdout和stderr将会被关联至父进程,否则,它们将会从父进程中继承。(默认为:false)
  • uid Number 设置用户进程的 ID
  • gid Number 设置进程组的 ID

返回的对象除了拥有ChildProcess实例的所有方法,还有一个内建的通信信道。

实例

让我们创建两个 js 文件 support.js 和 master.js。

support.js 文件代码:

console.log("进程 " + process.argv[2] + " 执行。" );

master.js 文件代码:

const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
  var worker_process = child_process.fork("support.js", [i]);  
 
  worker_process.on('close', function (code) {
   console.log('子进程已退出,退出码 ' + code);
  });
}

执行以上代码,输出结果为:

$ node master.js
进程 0 执行。
子进程已退出,退出码 0
进程 1 执行。
子进程已退出,退出码 0
进程 2 执行。
子进程已退出,退出码 0

以上就是详细分析Node.js 多进程的详细内容,更多关于Node.js 多进程的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
表单(FORM)的一些实用效果代码
Mar 25 Javascript
Javascript 读后台cookie代码
Sep 15 Javascript
jQuery lazyload 的重复加载错误以及修复方法
Nov 19 Javascript
window.open以post方式将内容提交到新窗口
Dec 26 Javascript
jquery解析xml字符串简单示例
Apr 11 Javascript
编写简单的jQuery提示插件
Dec 21 Javascript
jQuery zTree加载树形菜单功能
Feb 25 Javascript
jquery自定义右键菜单、全选、不连续选择
Mar 01 Javascript
运用js教你轻松制作html音乐播放器
Apr 17 Javascript
获取今天,昨天,本周,上周,本月,上月时间(实例分享)
Jan 04 Javascript
js获取元素的偏移量offset简单方法(必看)
Jul 05 Javascript
vue点击按钮实现简单页面的切换
Sep 08 Javascript
详细分析vue响应式原理
Jun 22 #Javascript
Vue循环遍历选项赋值到对应控件的实现方法
Jun 22 #Javascript
如何解决jQuery 和其他JS库的冲突
Jun 22 #jQuery
解决Vue 给mapState中定义的属性赋值报错的问题
Jun 22 #Javascript
支付宝小程序实现省市区三级联动
Jun 21 #Javascript
微信小程序实现canvas分享朋友圈海报
Jun 21 #Javascript
微信小程序实现选择地址省市区三级联动
Jun 21 #Javascript
You might like
关于文本留言本的分页代码
2006/10/09 PHP
php使用CURL伪造IP和来源实例详解
2015/01/15 PHP
PHP往XML中添加节点的方法
2015/03/12 PHP
php变量与字符串的增删改查操作示例
2020/05/07 PHP
一些相见恨晚的 JavaScript 技巧
2010/04/25 Javascript
js中top、clientTop、scrollTop、offsetTop的区别 文字详细说明版
2011/01/08 Javascript
自己编写的支持Ajax验证的JS表单验证插件
2015/05/15 Javascript
jquery分析文本里url或邮件地址为真实链接的方法
2015/06/20 Javascript
Jquery 分页插件之Jquery Pagination
2015/08/25 Javascript
详解iframe与frame的区别
2016/01/13 Javascript
深入理解JavaScript单体内置对象
2016/06/06 Javascript
总结在前端排序中遇到的问题
2016/07/19 Javascript
JavaScript实现京东购物放大镜和选项卡效果的方法分析
2018/07/05 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
在Python中使用元类的教程
2015/04/28 Python
Python基于贪心算法解决背包问题示例
2017/11/27 Python
python utc datetime转换为时间戳的方法
2019/01/15 Python
用python拟合等角螺线的实现示例
2019/12/27 Python
python等差数列求和公式前 100 项的和实例
2020/02/25 Python
python 高阶函数简单介绍
2021/02/19 Python
pandas按条件筛选数据的实现
2021/02/20 Python
迪拜领先运动补剂零售品牌中文站:Sporter商城
2019/08/20 全球购物
旅游与酒店管理的自我评价分享
2013/11/03 职场文书
社区党总支书记先进事迹材料
2014/01/24 职场文书
中秋寄语大全
2014/04/11 职场文书
省文明单位申报材料
2014/05/08 职场文书
企业宗旨标语
2014/06/10 职场文书
玩手机检讨书1000字
2014/10/20 职场文书
2014会计年终工作总结
2014/12/20 职场文书
初中差生评语
2014/12/29 职场文书
统计员岗位职责
2015/02/11 职场文书
《坐井观天》教学反思
2016/02/18 职场文书
python使用pygame创建精灵Sprite
2021/04/06 Python
Go语言操作数据库及其常规操作的示例代码
2021/04/21 Golang
SpringCloud的JPA连接PostgreSql的教程
2021/06/26 Java/Android
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
2022/08/05 Vue.js