2020-04-19
Node
0

目录

exec
execFile
spawn
fork
创建和父模块分离的子进程
总结

本篇对Node child_process进行深入了解,child_process开启子进程的方法有exec、execFile、spawn、fork。

注意事项

  • 子进程会在执行完命令以后,自动被关闭,除非进程里面的代码一直在运行
  • 如果在fork进程中出现父子进程相互发消息的情况,则不会自动关闭,需要手动进行关闭。

exec

  1. 运行完所有内容以后,才会进入callback
  2. 超出maxBuffer以后,进程会被自动终止
  3. options的shell默认值为true,会衍生一个 shell,然后在 shell 中执行 command,且缓冲任何产生的输出
js
exec('cat read.txt',(error, stdout, stderr)=>{ if (error) { console.error(`执行的错误: ${error}`); return; } console.log(`stdout: ${stdout}`); console.error(`stderr: ${stderr}`); })

execFile

  1. 和exec第一点相同
  2. 和exec第二点相同
  3. options的shell默认值为false。不会衍生 shell。 相反,指定的可执行文件 file 会作为新进程直接地衍生,使其比 child_process.exec() 稍微更高效,但是无法执行 I/O 重定向和文件通配等行为
js
execFile('cat',['read.txt','>','a.txt'],(error, stdout, stderr)=>{ if (error) { throw error; } console.log('stdout',stdout); console.log('stderr',stderr); })

spawn

  1. 采用流的形式接收数据和导出数据
  2. 可以解除maxBuffer限制
  3. 和execFile第三点相同
js
const { spawn } = require('child_process'); const ps = spawn('ps', ['ax']); const grep = spawn('grep', ['ssh']); ps.stdout.on('data', (data) => { grep.stdin.write(data); }); ps.stderr.on('data', (data) => { console.error(`ps stderr: ${data}`); }); ps.on('close', (code) => { console.log('ps close') if (code !== 0) { console.log(`ps 进程退出,退出码 ${code}`); } grep.stdin.end(); }); grep.stdout.on('data', (data) => { console.log(data.toString()); }); grep.stderr.on('data', (data) => { console.error(`grep stderr: ${data}`); }); grep.on('close', (code) => { console.log('grep close') if (code !== 0) { console.log(`grep 进程退出,退出码 ${code}`); } });

fork

  1. 采用流的形式接收数据和导出数据
  2. 无法执行命令
  3. 与父进程共享一个 IPC 通道,用于父子通信
js
// parent.js const { fork } = require('child_process'); const child = fork('./child.js'); child.on('message', (message) => { console.log(`Received message from child: ${message}`); }); child.send('Hello from parent'); // child.js process.on('message', (message) => { console.log(`Received message from parent: ${message}`); process.send('Hello from child'); });

创建和父模块分离的子进程

  1. 通过 detached:true 使子进程脱离父进程。
  2. 将子进程与父进程的IO分离,需要配置 stdio
  3. 移除父进程对子进程的引用,使用 child_process.unref()
js
setInterval(() => { console.log('父进程') },2000) const subprocess = spawn('node', ['detached.js'], { detached: true, stdio: 'ignore' }); subprocess.unref(); // detached.js setInterval(()=>{ console.log('子进程') },1000)

总结

  1. spawn 用于直接使用的命令,交互通过child.stdout进行
  2. exec和execFile也直接用于命令,交互通过回调进行
  3. fork用户执行文件,可以进行父子通信

本文作者:BARM

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!