详细分析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 相关文章推荐
禁止js文件缓存的代码
Apr 09 Javascript
JavaScript中判断整数的多种方法总结
Nov 08 Javascript
jQuery中first()方法用法实例
Jan 06 Javascript
js实现跨域的多种方法
Dec 25 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
Oct 26 Javascript
关于js函数解释(包括内嵌,对象等)
Nov 20 Javascript
Node.js中sequelize时区的配置方法
Dec 10 Javascript
vue自定义全局组件(自定义插件)的用法
Jan 30 Javascript
jQuery实现点击自身以外区域关闭弹出层功能完整示例【改进版】
Jul 31 jQuery
使用Vue实现调用接口加载页面初始数据
Oct 28 Javascript
vue.js自定义组件实现v-model双向数据绑定的示例代码
Jan 08 Javascript
开发Node CLI构建微信小程序脚手架的示例
Mar 27 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
PHP中函数内引用全局变量的方法
2008/10/20 PHP
PHP中计算字符串相似度的函数代码
2012/12/29 PHP
php使用Jpgraph绘制柱形图的方法
2015/06/10 PHP
php生成静态html页面的方法(2种方法)
2015/09/14 PHP
PHP函数nl2br()与自定义函数nl2p()换行用法分析
2016/04/02 PHP
FireFox JavaScript全局Event对象
2009/06/14 Javascript
基于JQuery的一句话搞定手风琴菜单
2012/09/14 Javascript
关于JS字符串函数String.replace()
2013/04/07 Javascript
js强制把网址设为默认首页
2015/09/29 Javascript
js实现页面跳转的五种方法推荐
2016/03/10 Javascript
JS读写CSS样式的方法汇总
2016/08/16 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
2017/01/19 Javascript
js实现3D图片展示效果
2017/03/09 Javascript
微信小程序之购物车功能
2020/09/23 Javascript
配置nodejs环境的方法
2017/05/13 NodeJs
webpack-dev-server自动更新页面方法
2018/02/22 Javascript
Electron autoUpdater实现Windows安装包自动更新的方法
2018/12/24 Javascript
vue请求本地自己编写的json文件的方法
2019/04/25 Javascript
vue@cli3项目模板怎么使用public目录下的静态文件
2020/07/07 Javascript
浅析 Vue 3.0 的组装式 API(一)
2020/08/31 Javascript
vue项目实现多语言切换的思路
2020/09/17 Javascript
[54:51]Ti4 冒泡赛第二轮LGD vs C9 3
2014/07/14 DOTA
python实现简单socket通信的方法
2016/04/19 Python
Python中的time模块与datetime模块用法总结
2016/06/30 Python
python tkinter实现屏保程序
2019/07/30 Python
关于Keras模型可视化教程及关键问题的解决
2020/01/24 Python
TensorFLow 变量命名空间实例
2020/02/11 Python
Python利用逻辑回归分类实现模板
2020/02/15 Python
美国最大的网上冲印店:Shutterfly
2017/01/01 全球购物
JD Sports法国:英国篮球和运动时尚的领导者
2017/09/28 全球购物
开工庆典邀请函范文
2014/01/16 职场文书
通用自荐信范文
2014/03/14 职场文书
婚礼秀策划方案
2014/05/19 职场文书
大学计划书范文800字
2014/08/14 职场文书
圆明园观后感
2015/06/03 职场文书
SONY600GR,国产收音机厂商永远的痛
2022/04/05 无线电