首页 > 语言 > JavaScript > 正文

Node.js中的child_process模块详解

2024-05-06 15:33:31
字体:
来源:转载
供稿:网友

前言

本文主要给大家介绍了关于Node.js中child_process模块的相关内容,在介绍child_process模块之前,先来看一个例子。

const http = require('http');const longComputation = () => { let sum = 0; for (let i = 0; i < 1e10; i++) { sum += i; }; return sum;};const server = http.createServer();server.on('request', (req, res) => { if (req.url === '/compute') { const sum = longComputation(); return res.end(`Sum is ${sum}`); } else { res.end('Ok') }});server.listen(3000);

可以试一下使用上面的代码启动Node.js服务,然后打开两个浏览器选项卡分别访问/compute和/,可以发现node服务接收到/compute请求时会进行大量的数值计算,导致无法响应其他的请求(/)。

在Java语言中可以通过多线程的方式来解决上述的问题,但是Node.js在代码执行的时候是单线程的,那么Node.js应该如何解决上面的问题呢?其实Node.js可以创建一个子进程执行密集的cpu计算任务(例如上面例子中的longComputation)来解决问题,而child_process模块正是用来创建子进程的。

创建子进程的方式

child_process提供了几种创建子进程的方式

异步方式:spawn、exec、execFile、fork 同步方式:spawnSync、execSync、execFileSync

首先介绍一下spawn方法

child_process.spawn(command[, args][, options])command: 要执行的指令args: 传递参数options: 配置项
const { spawn } = require('child_process');const child = spawn('pwd');

pwd是shell的命令,用于获取当前的目录,上面的代码执行完控制台并没有任何的信息输出,这是为什么呢?

控制台之所以不能看到输出信息的原因是由于子进程有自己的stdio流(stdin、stdout、stderr),控制台的输出是与当前进程的stdio绑定的,因此如果希望看到输出信息,可以通过在子进程的stdout 与当前进程的stdout之间建立管道实现

child.stdout.pipe(process.stdout);

也可以监听事件的方式(子进程的stdio流都是实现了EventEmitter API的,所以可以添加事件监听)

child.stdout.on('data', function(data) { process.stdout.write(data);});

在Node.js代码里使用的console.log其实底层依赖的就是process.stdout

除了建立管道之外,还可以通过子进程和当前进程共用stdio的方式来实现

const { spawn } = require('child_process');const child = spawn('pwd', { stdio: 'inherit'});

stdio选项用于配置父进程和子进程之间建立的管道,由于stdio管道有三个(stdin, stdout, stderr)因此stdio的三个可能的值其实是数组的一种简写

pipe 相当于['pipe', 'pipe', 'pipe'](默认值) ignore 相当于['ignore', 'ignore', 'ignore'] inherit 相当于[process.stdin, process.stdout, process.stderr]
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选