node的process以及child_process模块学习笔记


Posted in Javascript onMarch 06, 2018

在死磕进程一个礼拜后,终于把晦涩难懂文档看明白了,准备把自己的理解分享给大家,也希望大家能指出一些意见

进程的概念

  1. 在Node.js中每个应用程序都是一个进程类的实例对象。
  2. 使用process对象代表应用程序,这是一个全局对象,可以通过它来获取Node.jsy应用程序以及运行该程序的用户、环境等各种信息的属性、方法和事件。

进程中几个重要的属性

  1. stdin 标准输入可读流
  2. stdout 标准输入可写流
  3. stderr 标准错误输出流
  4. argv 终端输入参数数组
  5. env 操作系统环境信息
  6. pid 应用程序进程id

stdin以及stdout

process.stdin.on('data', (chunk) => {
 process.stdout.write('进程接收到数据' + chunk)
})

运行结果

node的process以及child_process模块学习笔记

argv

console.log(process.env)

node的process以及child_process模块学习笔记

env: 在mac终端输入 export NODE_ENV=develop

console.log(process.env.NODE_ENV) //develop

进程的方法

  1. process.memoryUsage() 查看内存使用信息
  2. process.nextTick() 当前eventloop执行完毕执行回调函数
  3. process.chdir() chdir方法用于修改Node.js应用程序中使用的当前工作目录
  4. process.cwd() 进程当前工作目录
  5. process.kill() 杀死进程
  6. process.uncaughtException() 当应用程序抛出一个未被捕获的异常时触发进程对象的uncaughtException事件
say() //方法不存在
process.on('uncaughtException',function(err){
 console.log('捕获到一个未被处理的错误:',err);
});

child_process

子进程是今天要讲的重点,我也有一些不太明白,希望能和大家多多交流

child_process出现的背景

在Node.js中,只有一个线程执行所有操作,如果某个操作需要大量消耗CPU资源的情况下,后续操作都需要等待。

在Node.js中,提供了一个child_process模块,通过它可以开启多个子进程,在多个子进程之间可以共享内存空间,可以通过子进程的互相通信来实现信息的交换。

child_process模块给予node任意创建子进程的能力,node官方文档对于child_proces模块给出了四种方法,映射到操作系统其实都是创建子进程。但对于开发者而已,这几种方法的api有点不同

child_process.exec(command[, options][, callback]) 启动
子进程来执行shell命令,可以通过回调参数来获取脚本shell执行结果

child_process.execfile(file[, args][, options][, callback])
与exec类型不同的是,它执行的不是shell命令而是一个可执行文件

child_process.spawn(command[, args][, options])仅仅执行一个shell命令,不需要获取执行结果

child_process.fork(modulePath[, args][, options])可以用node
执行的.js文件,也不需要获取执行结果。fork出来的子进程一定是node进程

spawn

语法:child_process.spawn(command, [args], [options])

  1. command 必须指定的参数,指定需要执行的命令
  2. args 数组,存放了所有运行该命令需要的参数
  3. options 参数为一个对象,用于指定开启子进程时使用的选项
const { spawn } = require('child_process')
const path = require('path')

let child1 = spawn('node', ['test1.js', 'yanyongchao'], {
 stdio: ['pipe', 'pipe', 'pipe'], // 三个元素数组 下面会详解
 cwd: __dirname, 子进程工作目录
 env: process.env, 环境变量
 detached: true // 如果为true,当父进程不存在时也可以独立存在
})

其实上面都好理解除了sdtio数组,下面来一起分析stdio

stdio

stdio是一个数组,用来设置标准输入,标准输出,错误输出。个人理解

pipe:父进程和子进程之间建立一个管道

主进程代码

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

let p = spawn('node', ['childs_t.js'], {
 cwd: path.join(__dirname, 'childs'),
 stdio: ['pipe', 'pipe', process.stderr]
})

p.stdout.on('data', (data) => {
 console.log(data.toString())
}) 
// 这里用stdout原因: 子进程的数据流与常规理解的数据流方向相反,
// stdin:写入流,stdout、stderr:读取流。

子进程代码

process.stdout.write('asd')

如果在stdio中放一个流,process.stdout,process.stdin

主进程代码

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

// 如果放的是一个流,则意味着父进程和子进程共享一个流
const p = spawn('node', ['child_t.js'], {
 cwd: path.join(__dirname, 'childs'),
 stdio: [process.stdin, process.stdout, process.stderr]
})

子进程代码

process.stdout.write('asd') //控制台会输出asd

ipc

主进程代码

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

let p = spawn('node', ['child_t.js'], {
 cwd: path.join(__dirname, 'childs'),
 stdio: ['ipc', 'pipe', 'pipe']
})

p.on('message', (msg) => {
 console.log(msg)
})

p.send('hello chhild_process')

子进程代码

process.on('message', (msg) => {
 process.send('子进程' + msg)
})
// child.send(message,[sendHandle]);//在父进程中向子进程发送消息
// process.send(message,[sendHandle]);//在子进程中向主进程发送消息

detached模式

const { spawn } = require('child_process')
const fs = require('fs')
const path = require('path')
let out = fs.openSync(path.join(__dirname, 'childs/msg.txt'), 'w', 0o666)

let p = spawn('node', ['test4.js'], {
 detached: true, //保证父进程结束,子进程仍然可以运行
 stdio: 'ignore',
 cwd: path.join(__dirname, 'childs')
})

p.unref()

p.on('close', function() {
 console.log('子进程关闭')
})

p.on('exit', function() {
 console.log('子进程退出')
})

p.on('error', function(err) {
 console.log('子进程1开启失败' + err)
})

fork开启一个子进程

  1. 衍生一个新的 Node.js 进程,并通过建立一个 IPC 通讯通道来调用一个指定的模块,该通道允许父进程与子进程之间相互发送信息
  2. fork方法返回一个隐式创建的代表子进程的ChildProcess对象
  3. 子进程的输入/输出操作执行完毕后,子进程不会自动退出,必须使用process.exit()方法显式退出

子进程代码

const { fork } = require('child_process')
const path = require('path')
let child = fork(path.join(__dirname, 'childs/fork1.js'))

child.on('message', (data) => {
 console.log('父进程接收到消息' + data)
})

child.send('hello fork')

child.on('error', (err) => {
 console.error(err)
})

子进程代码

process.on('message', (m, setHandle) => {
 console.log('子进程接收到消息' + m)
 process.send(m) //sendHandle是一个 net.Socket 或 net.Server 对象
})

exec开启子进程

// exec同步执行一个shell命令
let { exec } = require('child_process')
let path = require('path')

// 用于使用shell执行命令, 同步方法

let p1 = exec('node exec.js a b c', {cwd: path.join(__dirname, 'childs')}, function(err, stdout, stderr) {
 console.log(stdout)
})

execFile开启子进程

let { execFile } = require('child_process')
let path = require('path')

let p1 = execFile('node', ['exec.js', 'a', 'b', 'c'], {
 cwd: path.join(__dirname, 'childs')
}, function(err, stdout, stderr) {
 console.log(stdout)
})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
深入理解javascript学习笔记(一) 编写高质量代码
Aug 09 Javascript
轻松学习jQuery插件EasyUI EasyUI创建RSS Feed阅读器
Nov 30 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
Apr 12 Javascript
在Mac下彻底卸载node和npm的方法
May 16 Javascript
vue v-model实现自定义样式多选与单选功能
Jul 05 Javascript
Vue 应用中结合vux使用微信 jssdk的方法
Aug 28 Javascript
关于vue编译版本引入的问题的解决
Sep 17 Javascript
ES6基础之展开语法(Spread syntax)
Feb 21 Javascript
微信小程序云开发如何使用云函数生成二维码
May 18 Javascript
深入浅出了解Node.js Streams
May 27 Javascript
JavaScript 防盗链的原理以及破解方法
Dec 29 Javascript
利用js实现简单开关灯代码
Nov 23 Javascript
Vue2.0实现组件数据的双向绑定问题
Mar 06 #Javascript
轻松搞定jQuery+JSONP跨域请求的解决方案
Mar 06 #jQuery
Vue2.0 http请求以及loading展示实例
Mar 06 #Javascript
浅析Vue中method与computed的区别
Mar 06 #Javascript
浅谈Koa2框架利用CORS完成跨域ajax请求
Mar 06 #Javascript
JavaScript基础心法 深浅拷贝(浅拷贝和深拷贝)
Mar 05 #Javascript
JavaScript基础心法 数据类型
Mar 05 #Javascript
You might like
PHP 和 XML: 使用expat函数(二)
2006/10/09 PHP
PHP开发负载均衡指南
2010/07/17 PHP
PHP版 汉字转码的实现详解
2013/06/09 PHP
基于JQuery实现滚动到页面底端时自动加载更多信息
2014/01/31 Javascript
Javascript中3个需要注意的运算符
2015/04/02 Javascript
使用javascript实现判断当前浏览器
2015/04/14 Javascript
javascript类型系统_正则表达式RegExp类型详解
2016/06/24 Javascript
使用vue编写一个点击数字计时小游戏
2016/08/31 Javascript
jQuery实现的浮动层div浏览器居中显示效果
2017/02/03 Javascript
Vue的MVVM实现方法
2017/08/16 Javascript
react native与webview通信的示例代码
2017/09/25 Javascript
微信小程序在地图选择地址并返回经纬度简单示例
2018/12/03 Javascript
node实现简单的增删改查接口实例代码
2019/08/22 Javascript
有趣的JavaScript隐式类型转换操作实例分析
2020/05/02 Javascript
JS this关键字在ajax中使用出现问题解决方案
2020/07/17 Javascript
[01:56]《DOTA2》中文配音CG
2013/04/22 DOTA
[50:01]Ti4 冒泡赛第二天 NEWBEE vs Titan
2014/07/15 DOTA
[02:42]完美大师赛主赛事淘汰赛第三日观众采访
2017/11/25 DOTA
用Python中的wxPython实现最基本的浏览器功能
2015/04/14 Python
将Django框架和遗留的Web应用集成的方法
2015/07/24 Python
python如何定义带参数的装饰器
2018/03/20 Python
Python 实现网页自动截图的示例讲解
2018/05/17 Python
Django框架登录加上验证码校验实现验证功能示例
2019/05/23 Python
python中的split()函数和os.path.split()函数使用详解
2019/12/21 Python
Tensorflow Summary用法学习笔记
2020/01/10 Python
Python unittest基本使用方法代码实例
2020/06/29 Python
python 使用cycle构造无限循环迭代器
2020/12/02 Python
Lookfantastic俄罗斯:欧洲在线化妆品零售商
2019/08/06 全球购物
给老婆大人的检讨书
2014/02/24 职场文书
幼儿园元旦活动感言
2014/03/02 职场文书
关于建议书的格式范文
2014/05/20 职场文书
大学毕业生个人自荐书
2014/07/02 职场文书
2014年政务公开工作总结
2014/12/09 职场文书
党风廉政建设个人总结
2015/03/06 职场文书
详解Redis主从复制实践
2021/05/19 Redis
20180830晚上第一届KSL半决赛 雨神vs解冻(二龙 三炮解说)
2022/04/01 星际争霸