创建子进程的几种方式

1、child_process.exec(command[, options][, callback])
2、child_process.execFile(file[, args][, options][, callback])
3、child_process.fork(modulePath[, args][, options])
4、child_process.spawn(command[, args][, options])
其中exec,execFile,fork均是从spawn衍生出来。

通道的建立和原理

stdout,stdin,stderr是共享了父进程的文件操作符,所以我们可以通过创建文件操作符来进行进程间共享,创建方法是fs.open或者fs.openSync

这四种的区别(只关注重点区别)

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

特点:
(1)衍生一个shell,然后在shell执行命令。相当于把command直接发送给shell执行。
(2)具有回调函数子进程结束或者意外退出会调用回调方法
(3)具有maxbuffer,stdout 或 stderr 上允许的最大字节数。如果超过限制,则子进程将终止。默认值: 200 * 1024。也因为如此,所以exec启用的子进程不适合与父进程发送大量数据。
(4)timeout,设置子进程的运行时间,如果大于0,子进程会在设定的时间过后接收到父进程发送的带 killSignal 属性(默认为 'SIGTERM')的信号。

2、child_process.execFile(file[, args][, options][, callback])

特点:
(1)用于执行可执行文件
(2)不衍生shell,使用可执行 file 直接作为新进程衍生,使其比 child_process.exec() 稍微更高效。
(3)具有maxbuffer,stdout 或 stderr 上允许的最大字节数。如果超过限制,则子进程将终止。默认值: 200 * 1024。也因为如此,所以exec启用的子进程不适合与父进程发送大量数据。
(4)timeout,设置子进程的运行时间,如果大于0,子进程会在设定的时间过后接收到父进程发送的带 killSignal 属性(默认为 'SIGTERM')的信号。
(5)由于没有生成 shell,因此不支持 I/O 重定向和文件通配等行为。

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

特点:
(1)是 child_process.spawn() 的一个特例,专门用于衍生新的 Node.js 进程。
(2)与 child_process.spawn() 一样返回 ChildProcess 对象。 返回的 ChildProcess 会内置一个额外的通信通道,允许消息在父进程和子进程之间来回传递。
(3)shell 选项在 child_process.fork() 中不支持,如果设置则会被忽略。
(4)可以设置stdio,但是必须包含一个额外的ipc通道
(5)可以在配置中指定execPath,这样便可以使用不同的node版本启动进程了

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

特点:
(1)以上三个方法有的功能均能通过这个方法实现

实现功能

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

这个方法能实现的功能比较多。
1、实现子进程通过stdio配置往一个文件中写内容

//主进程
const {spawn}=require('child_process');
const fs=require('fs');//获取文件描述符
let fd=fs.openSync('./a.temp','r+');let child1=spawn('node',['./child1.js'],{stdio:['pipe',fd,'pipe']
});
复制代码
//子进程process.stdin.on('data',(data)=>{console.log(data)
})
setInterval(()=>{process.stdout.write('哈哈哈','utf-8')
},20)复制代码

2、指定环境变量

//主进程
const {exec}=require('child_process');let child=exec('node ./child.js',{env:{mode:'dev'}
},(err,stdout,stderr)=>{console.log(stdout)
})
//child
process.stdout.write(process.env.mode)
//输出dev
复制代码

3、父子进程解除引用
解除引用大的前提有以下几点:
(1)、父子进程之间不能共享stdio,ipc。
(2)、detached:true,需要配置此项。

//让父进程脱离子进程配置
let child= spawn('node',['./child.js'],{detached:true,stdio:"ignore"})
复制代码

4、设置编码
以下演示设置编码的两种方式。

const {spawn,exec}=require('child_process');//使用spawn的编码方式
let childSpawn=spawn('node',['-v']);
childSpawn.stdout.setEncoding('utf8');childSpawn.stdout.on('data',(data)=>{console.log(data)
})//这种方式显而更简单
let childExec=exec('node -v',{encoding:'utf8'},(err,stdout,stdin)=>{})childExec.stdout.on('data',(data)=>{console.log(data)
})复制代码

5、设置maxBuffer
maxBuffer的含义是接受到的字节总数,这个的作用是可以防止父进程不处理数据子进程一直写入导致内存爆掉。

//主进程
const {spawn,exec}=require('child_process');let  maxBufferLength=1024*1200;
let childSpawn=spawn('node',['./child.js']);
let  sum=0;
childSpawn.stdout.on('data',(data)=>{sum=sum+Buffer.byteLength(data);if(sum>=maxBufferLength){childSpawn.kill('SIGTERM')}
})
childSpawn.on('exit',(code,sig)=>{console.log(sig)
})//使用exec限流let  childExec=exec('node ./child.js',{maxBuffer:maxBufferLength},(err,stdout,stderr)=>{console.log(err)
})childExec.on('exit',(code,sig)=>{console.log(sig)
})
//child.js
setInterval(()=>{process.stdout.write(Buffer.alloc(1024*400,"hha"))
},1000)
复制代码

6、设置timeOut
设置timeOut

const {spawn,exec}=require('child_process');let  timeOut=3000;
let childSpawn=spawn('node',['./child.js']);
childSpawn.stdout.on('data',(data)=>{})
setTimeout(()=>{childSpawn.kill('SIGTERM')
},timeOut);childSpawn.on('exit',(code,sig)=>[console.log(sig)
])//使用exec设置超时
let  childExec=exec('node ./child.js',{timeout:timeOut},(err,stdout,stderr)=>{console.log(err)
})childExec.on('exit',(code,sig)=>[console.log(sig)
])
//child.js
setInterval(()=>{process.stdout.write(Buffer.alloc(1024*400,"hha"))
},1000)
复制代码

转载于:https://juejin.im/post/5c98bc7ff265da6106148a62

child_process使用记录相关推荐

  1. shell脚本spawn_如何使用child_process.spawn将Python / Ruby / PHP Shell脚本与Node.js集成

    shell脚本spawn There are occasions when running a Python/Ruby/PHP shell script from Node.js is necessa ...

  2. 详细记录一次npm i canvas报错的解决过程

    npm i canvas 报错信息 $ npm i canvas> canvas@1.6.13 install /Users/jayson/Documents/workspace/xuebang ...

  3. Node.js中的child_process模块详解

    本文主要给大家介绍了关于Node.js中child_process模块的相关内容,在介绍child_process模块之前,先来看一个例子. const http = require('http'); ...

  4. electron + vue /打包linux应用报错记录

    1. electron + vue 打包linux应用报错记录 >  icon图标导致的报错 ⨯ unknown output format set github.com/develar/app ...

  5. 关于gyp ERR node-gyp gyp ERR node -v错误记录

    重要出错信息 gyp ERR! node -v v14.15.3 gyp ERR! node-gyp -v v5.1.0 fatal error: too many errors emitted, s ...

  6. 远程实验平台开发记录(毕业前把做过的东西整理下)

    远程实验平台开发记录(2018-2020) 1. Python flask开发网站 web开发入门: https://blog.csdn.net/weixin_40929147/article/det ...

  7. node命令行交互与child_process实战

    1. 前言   随着项目的逐步膨胀和复杂,我们在实际的工程应用中会通过编写各种各样的脚本来提高效率,传统的方法是在项目的package.json文件中注册各种各样的命令,来完成打包,构建,打包分析等操 ...

  8. mysql建立联合索引,mysql建立唯一键,mysql如何解决重复记录联合索引

    在项目中,常常要用到联合唯一   在一些配置表中,一些列的组合成为一条记录.   比如,在游戏中,游戏的分区和用户id会形成一条记录.(比如,一个qq用户可以在艾欧尼亚.德玛西亚创建两个账号) 添加联 ...

  9. 实现 连续15签到记录_MySQL和Redis实现用户签到,你喜欢怎么实现?

    现在的网站和app开发中,签到是一个很常见的功能 如微博签到送积分,签到排行榜 微博签到 如移动app ,签到送流量等活动, 移动app签到 用户签到是提高用户粘性的有效手段,用的好能事半功倍! 下面 ...

最新文章

  1. java节假日api--关于节假日想到的
  2. csu 1757(贪心或者树状数组)
  3. 2020年高等数学方法与提高(上海理工大学)学习笔记:一元函数积分学
  4. An In-Depth Look at the HBase Architecture--转载
  5. 成功解决ValueError: Invalid format string
  6. java源码 1.8_Java源码下载和阅读(JDK1.8/Java 11)
  7. mysql实现程序的动态链接_程序的链接和装入及Linux下动态链接的实现
  8. 鸿蒙空间是什么星辰变,飞升之后做什么《星辰变》神魔妖界收伏奇珍异兽
  9. otc机器人氩弧焊机_历经100年,这家公司成为弧焊机器人领域的世界王者
  10. Python制作翻译软件(中英文互译)
  11. linux系统添加网卡驱动,linux添加网卡及驱动
  12. 拉里·佩奇(Larry Page)的伟大归来
  13. 活着就是要做有意义的事,做有意义的事就是好好活着
  14. 解决from Crypto.Cipher import AES报错
  15. lncRNA数据分析专题
  16. 【完美解决】修复concrt140.dll未找到错误的问题
  17. qmail邮件为什么退信_调整为QMail
  18. 大学生穷游网 项目截图
  19. 三年前端,面试思考(头条蚂蚁美团offer)
  20. 一个码农关于足球的记忆

热门文章

  1. 人工智能 02. 图像识别
  2. python爬取百度地图数据_百度地图POI数据爬取
  3. 【C语言趣味教程】typedef 真爽不爽不要玩 | 初识结构体
  4. 计算机玩游戏怎么会突然有边框,电脑打游戏怎么设置全屏
  5. linux 系统swap设置,Linux 系统swap 设置
  6. python中readlines是什么意思_Python中read,readline,readlines三种方式的区别
  7. android 输入日语 外键盘,日语外来语怎么用键盘输入
  8. 《高效程序员的修炼》读后感
  9. 实现手机扫码直接拨打电话
  10. 声明一个Tree(树)类,有成员ages(树龄),成员函数grow(int years)用以对ages 加上years,showage( )用以显示tree对象的ages值。在主函数中定义Tree类对