93. child_process
child_process Node.js 全解-子进程 目录
进程
线程
Node.js的进程控制
Node.jis的线程控制
进程 Process
场景
notepad.exe是一个程序,不是进程
双击 notepad.exe 时, 操作系统会开启一个进程
定义
进程是程序的执行实例
程序在CPU上执行时的活动叫做进程
实际上并没有明确的定义,只有一些规则
特点
一个进程可以创建另一个进程 (父进程与子进程)
通过任务管理器可以看到进程
了解CPU
特点
一个单核 CPU,在一个时刻, 只能做一件事情
那么如何让用户同时看电影、听声音、 写代码呢?
答案是在不同进程中快速切换
此处以渣男交多个女朋友举例
多程序并发执行
指多个程序在宏观上并行,微观上串行
每个进程会出现 「执行-暂停-执行」的规律
多个进程之前会出现抢资源 (如打印机) 的现象
进程的两个状态
阻塞(se)
等待执行的进程中
都是非运行态
一些(A)在等待CPU资源
另一些(B)在等待1/0 完成(如文件读取)
如果这个时候把CPU分配给B进程,B还是在等I/O
我们把这个B叫做阻塞进程
因此,分派程序只会把CPU分配给非阻塞进程
进程的三个状态
线程Thread的引入
分阶段
在面向进程设计的系统中,进程是程序的基本执行实体
在面向线程设计的系统中,进程本身不是基本运行单位,
而是线程的容器
引入原因
进程是执行的基本实体,也是资源分配的基本实体
导致进程的创建、切换、销毁太消耗CPU时间了
于是引入线程,线程作为执行的基本实体
而进程只作为资源分配的基本实体
此处可以以设计师和工程师分开招聘举例
线程Thread
概念
CPU调度和执行的最小单元
一个进程中至少有一个线程,可以有多个线程
一个进程中的线程共享该进程的所有资源
进程的第--个线程叫做初始化线程
线程的调度可以由操作系统负责,也可以用户自己负责
举例
浏览器进程里面有渲染引擎、 V8引擎、 存储模块、网络模块、用户界面模块等
每个模块都可以放在一个线程里
分析
子进程V.S.线程
child process
用于新建子进程
child_process
使用目的
去执行一个命令行程序
子进程的运行结果将储存在系统缓存之中(最大200Kb)
等到子进程运行结束以后,主进程再用回调函数读取子
进程的运行结果
有两种方式获取child_process的执行结果,一种是用标准输出,一种是用流。
API - exec
exec(cmd,options, fn)
execute 的缩写,用于执行bash命令
同步版本: execSync
流
返回一个流
Promise
可以使其 Promise 化,用util.promisify
有漏洞
如果 cmd 被注入了,可能执行意外的代码, 比如把根目录全部删掉
推荐使用 execFile
使用流
options
几个常用的选项
cwd - Current working directory
env-环境变量
shell-用什么 shell
maxBuffer-最大缓存,默认1024* 1024字节
API - execFile
执行特定的程序
命令行的参数要用数组形式传入,无法注入
如果使用流的话,就不需要传后面的回调函数,而且不会引发注入。
同步版本:execFileSync
支持流吗? 试一试就知道了
API - Spawn
Spawn
spawn是产卵的意思。
用法与execFile方法类似
没有回调函数,只能通过流事件获取结果
没有最大200Kb的限制(因为是流)
经验
能用spawn的时候就不要用execFile, 因为execFile有回调限制,最大200kb
API - fork
fork
创建一个子进程,执行Node脚本
fork('./child.js')
相当于spawn('node', [./child.js'])
fork是spawn的语法糖
特点
会多出一个message事件,用于父子通信
会多出一个send方法
见下页
代码
n.js
.child.js
那怎么操作线程呢
刚才讲的都是进程啊
一些历史
child process. exec
v0.1.90加入Node.js
new Worker
v10.5.0加入Node.js
vl1.7.0之前需要--experimental-worker开启
这个线程API太新了
所以我们应该不会经常用到
效率
workerthreads API
API列表
isMainThread
new Worker(filename)
postMessage
事件列表
message
exit
再见
如果你对进程、线程感兴趣推荐学习任意一本 关于操作系统的教科书
方方看得是《操作系统原理》, 不推荐黑皮书
常用的是spawn和fork,spawn用来执行任意程序,fork用来执行nodejs的程序
最后更新于
这有帮助吗?