const {spawn} = require('child_process'); let cp1 = spawn('node', ['1.js'], { cwd: process.cwd(), env: process.env, stdio: ['pipe', process.stdout, 'pipe'], detached: false }); //子进程所有输入/输出终止时,会触发子进程的 'close' 事件 cp1.on('close', function (code, signal) { //当父进程关闭子进程时,signal表示父进程发送给子进程的信号名称 console.log('子进程关闭了', code, signal); }); //子进程退出时,会触发 'exit' 事件 //注意,子进程退出,子进程的输入/输出有可能并未关闭。因为输入/输出有可能多个进程共享。 cp1.on('exit', function (code, signal) { console.log('子进程退出', code, signal); }); //子进程出错时,触发 cp1.on('error', function (err) { console.log(err); });
注意,stdio 设置成 pipe ,是把子进程的stdin,stdout,stderr导向了 spawn() 返回的子进程对象的stdin,stdout,stderr。
然后父进程就可以通过子进程对象访问stdin,stdout,stderr。
const {spawn} = require('child_process'); let cp1 = spawn('node', ['1.js'], { cwd: process.cwd(), env: process.env, stdio: ['pipe', 'pipe', 'pipe'], detached: false }); //监听子进程标准输入,输出,错误的数据。 cp1.stdin.on('data', function (data) { console.log(data.toString()); }); cp1.stdout.on('data', function (data) { console.log(data.toString()); }); cp1.stderr.on('data', function (data) { console.log(data.toString()); });
1.js的代码:
//往子进程标准输出中写入数据 console.log('我是标准输出'); //往子进程错误中写入数据 console.error('我是一个错误'); //往子进程标准输入中写入数据 process.stdin.write('我是标准输入');
当我们设置 stdio 为 ipc 时,会创建一个父进程与子进程传递消息的IPC通道。
const {spawn} = require('child_process'); let cp1 = spawn('node', ['1.js'], { cwd: process.cwd(), env: process.env, //注意这里,子进程只能有一个IPC通道 stdio: ['pipe', 'ipc', 'pipe'], detached: false }); //注意这里要用子进程对象进行监听 //监听有没有消息 cp1.on('message', function (data) { console.log('子进程发送的 : ', data.toString()); }); cp1.send('你好,子进程');
1.js的代码:
process.on('message', function (data) { console.log('父进程发送的 : ', data.toString()); }); //向父进程发送消息 process.send('你好,父进程');
默认情况下,只有子进程全部退出了,父进程才能退出。我们希望父进程退出了,子进程仍然独立运行。可以通过设置 detached 为 true。
默认情况下,父进程会等待所有子程退出后,才退出。通过使用 unref() 让父进程无需等待子进程就可直接退出。
const {spawn} = require('child_process'); const fs = require('fs'); let fd = fs.openSync('./1.txt', 'w', 0o666); let cp1 = spawn('node', ['1.js'], { cwd: process.cwd(), //注意这里,把不需要的设置为ignore,不然主进程仍然会阻塞等待子进程 stdio: ['ignore', fd, 'ignore'], detached: true }); cp1.on('error', function (err) { console.log(err); }); //解绑子进程,让父进程不用等待子进程 cp1.unref();
1.js的代码:
let i = 0; let timer = setInterval(function () { if (i > 20) { clearInterval(timer); } process.stdout.write('写入数据' + i + '\r\n'); i++; }, 1000);
2、通过 fork() 创建子进程
fork() 是 spawn() 的特殊情况,用于创建新的进程,默认建立一个IPC通信通道,允许父进程与子进程进行消息传递。
fork() 返回一个子进程对象,子进程输入/输出操作执行完毕后,父进程不退出,子进程不会自动退出,需调用 exit() 显式退出。
const {fork} = require('child_process'); //参数一表示,运行的模块 //参数二表示,参数列表 //参数三表示,创建子进程的配置 let cp1 = fork('2.js', ['1', '2', '3'], { //子进程的工作目录 cwd: process.cwd(), //子进程的环境变量 env: process.env, //运行模块的可执行文件 execPath: process.execPath, //传递给可执行文件的参数列表 execArgv: process.execArgv, //为false表示父进程与子进程共享标准(输入/输出),为true时不共享。 silent: false }); cp1.on('error', function (err) { console.log(err); });
2.js的代码:
for (let i = 0; i < process.argv.length; i++) { process.stdout.write(process.argv[i] + '\r\n'); }
父进程与子进程间,通过 send() 和 'message'事件来传递消息。