在了解child_processz以前,咱们先来了解几个计算机操做系统中的基本概念,以及他们之间存在的关系。html
cup: 计算机包含五大基本硬件运算器、控制器、存储器、输入,输出设备。运算器和控制器集成为中央处理单元即CPU(Central Processing Unit),其主要做用是执行一系列指令运算而后将结果写回。node
进程: 进程是系统进行资源分配和调度的基本单位,同一时间在单个CUP上只能有一个进程运行,它会占用独立的内存。可是咱们可能会想到,计算机运行的时候确定不仅是只有一个进程在运行。在现代操做系统中,全部进程会轮流使用cpu,可是因为cpu的运行效率极高,能够在多个任务间快速切换,给咱们的感受就好像多个任务在并发执行。shell
线程: 线程是进程中的实体,一个进程能够拥有多个线程,一个线程必须有一个父进程。线程不拥有系统资源,线程共享该进程所拥有的所有资源,可是当有其中一个线程使用某一块共享内存的时候,其余线程必须等待它结束后,才能使用这一块内存。api
咱们知道node是单线程运行的,当咱们用node app.js启动node服务的时候会在服务器上运行一个node的进程,咱们的js代码只会在其中的一个线程运行。在node的设计中就是将耗时长的操做代理给操做系统或者其余线程,这部分操做就是磁盘I/O和网络I/O等常见的异步操做,而且将这些耗时的操做从主线程上脱离。虽然node从语言层面不支持建立线程,可是咱们能够经过child_process模块建立一个新的进程完成耗时耗费资源的操做,好比说要执行一段上传或下载大文件的shell脚本,而后将执行结果回传给主线程。服务器
使用child_process建立子进程的方式主要有如下四种:
exec、execFile、spawn、fork、
关于其各自的用法请自行查阅文档
process_child文档网络
这里咱们只对一些重要的须要注意的点,以及他们各自的使用场景作一个总结并发
child_process.exec(command, {...config}, (err, stdout, stderr) => {})
在exec方法的第二个参数中有这么一项配置即{maxBuffer: 200 * 1024}。它表示stdout、stderr 容许的最大输出大小(以 byte 为单位),若是超过了,子进程将被 kill 掉(发送 killSignal 值),它的默认值是200kb,这也就很大程度上决定了它的实用场景,即在子进程长时间运行或者大量的日志输出时,须要谨慎设置maxBuffer的值。这种状况下使用spawn方法更为合适。app
spawn(command, args, config)
spawn方式适合用在进程的输入、输出数据量比较大的状况能够用于任何命令。可是它与exec方法比较起来就是在执行多条命令的时候使用起来可能不太方便。若是咱们要执行多条命令,能够经过新建shell脚本的方式来实现。ssh
import { spawn } from 'child_process' const child = spawn('sh', [path.join(__dirname, './test.sh'), '192.100.100.100'])
而后在shell脚本里面执行下面的命令异步
ssh suoper@$1 << eeooff cd ${apiConfig.apkUpload.path} exit eeooff
fork(filePath, args, options)
fork命令只能执行用来执行node脚本,同事会建立一个新的V8实例。
execFile(file, args, options, callback)
须要注意的是,exec 会首先建立一个新的 shell 进程出来,而后执行 command。execFile 则是直接将可执行的 file 建立为新进程执行。因此,execfile 会比 exec 高效一些。exec 比较适合用来执行 shell 命令,而后获取输出(好比:exec('ps aux | grep "node"')),可是 execFile 却没办法这么用,由于它实际上只接受一个可执行的命令,而后执行(无法使用 shell 里面的管道之类的东西)。