child_process子进程
概念
child_process子进程是NodeJS的核心API,如果你会 shell命令 这个API对你帮助很大,
适合做一些cpu密集的任务
创建子进程
NodeJS创建子进程有 7个API 携带 Sync是同步执行 没有Sync的是异步执行
exec
-
child_process.exec(command, [options], callback)-
command执行的命令 如node -v -
options可选参数有以下几个参数
-
cwd指定命令在那个工作目录执行 默认值是process.cwd()父进程的根目录- 假如工作目录在
D:/home/user/project
const { exec } = require('node:child_process'); exec('cd', { cwd: process.cwd() // 默认值 },(error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log(`stdout: ${stdout}`); // 应输出类似于 'D:/home/user/project' }) - 假如工作目录在
-
-
encoding设置编码格式 默认是UTF8 -
timeout设置子进程执行最大时间,超过则报超时 默认为0 即等待子进程执行完毕 -
shell设置以什么的脚本执行shell -
在 Windows 系统上,默认的
shell是'cmd.exe'(命令提示符)。-
在 Unix-like 系统上(如 Linux 和 macOS),默认的
shell是'/bin/sh'。 -
maxBufferstdout和stderr允许的最大字节数。 默认为 200*1024。 如果超过限制,则子进程会被终止 -
举例: 如果我设置
maxBuffer为 10Mb 当stdout字节数是6MB 和stderr5MB 这样就会报错 -
killSignal 以什么样的方式退出子进程
-
默认值
SIGTERM将子进程的东西清理完毕后 再退出进程 -
SIGINT直接退出子进程 -
env给子进程设置环境变量 -
gid群组id 类似于后台管理系统的角色 -
uid用户id 类似于后台管理系统的用户
-
const { exec } = require('node:child_process'); exec('cd', { cwd: process.cwd() // 默认值 },(error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log(`stdout: ${stdout}`); // 应输出类似于 'D:/home/user/project' }); -
在 /database_script.js 中,成功给子进程设置了一个环境变量
console.log(process.env) // 其中 ADATEBASE: 'http://local:8080' ....
execSync
child_process.execSync(command, [options])是exec的同步任务- options 参数跟上面类似
const {execSync} = require('child_prcess')
const ex = execSync('dir',{});
console.log(ex.toString()); // v16.14.2
execSync("start chrome http://www.baidu.com --incognito") // 打开谷歌 无痕浏览
execFile和execFileSync
-
child_process.execFile(command, [args] [options], callback) -
child_process.execFileSync(command, [args] [options]) -
execFile 只能执行 本身电脑能运行的文件 如
cmd
echo '开始'
mkdir test
cd ./test
echo console.log("test1232131") >test.js
echo '结束'
node test.js
使用execFile 执行这个
execFile(path.join(process.cwd(), './bat.cmd'), (err, data) => {
console.log('data', data);
});
注意:execFile函数默认只能执行操作系统能够直接识别的可执行文件,对于像 Node.js、Java 或 Python 这样的脚本或编程语言,它们的文件(如 .js、.java 或 .py 文件)本身并不是可执行文件,而是需要相应的解释器或编译器来执行。
使用execFile 执行 .js 文件
execFile('node', [path.join(process.cwd(), './utils/index.js')], null, (err, stdout) => {
console.log(stdout.toString()); // hello node
});
在./utils/index.js文件中
console.log('hello node')
execFileSync同步执行js文件
const item = execFileSync('node', [path.join(process.cwd(), './utils/index.js')]);
console.log('item', item.toString());// hello node
spawn和spawnSyc
为什么有spawn 他和exec,execFile 的区别是啥呢,
-
spawn 获取的实时的信息,处理返回字节数据量比较大的时候使用特别好,
execexecFile会有返回大小限制 约200k 超出则会报错 这个时候使用spawn是一个明智的选择 -
spawn(command, [args] [options])const { stderr, stdout } = spawn('ping', ['www.baidu.com']); stdout.on('data', (data) => { console.log(data.toString()); }); stderr.on('data',(err)=>{ console.log('报错',err) }) -
spawn也可以处理文件
-
举例使用
js文件const { stderr, stdout } = spawn('node', [path.join(prcocess.cwd(),'./myIndex,js'),'xxx','aaa']); stdout.on('data', (data) => { console.log(data.toString()); }); stderr.on('data',(err)=>{ console.log('报错',err) }) -
在
myIndex,js文件中console.log('process.argv')// 'xxx','aaa' console.log('hello') // hello
-
注意:exec是底层通过execFile实现 execFile底层通过spawn实现
fork开启线程
-
适合做大量计算 会阻塞主任务的时候开启另一个线程实现
-
如在
index.jsconst child = fork(path.join(process.cwd(), './utils/child.js')); child.on('message', (data) => { console.log('data', data); }); child.send('哈哈哈我是主进程');在
./utils/child.js文件中process.on('message', (msg) => { console.log(msg); }); process.send('你好我是子进程');send 发送信息 ,message接收消息,可以相互发送接收。
fork底层使用的是IPC通道进行通讯的,