Node.js 本身是一个单线程的模式,但有些时候还是需要子进程的模式来处理某些需求
child_process 模块
该模块有一些方法能创建子进程
//exec、spawn: 创建子进程、执行shell 命令
//前者返回的进程创建缓存结果。后者返回的是一个 stream 流
const { exec, spawn } = require('child_process');
/*
三个参数:
1. shell 命令
2. 配置项:一般不用专门配置
3. 回调函数:也是传入三个参数
a.创建子进程时的错误
b. 创建成功后 shell 命令也成功
c. 创建成狗后 shell 命令失败
*/
/* exec('cat a.js', { shell: true, encoding: 'utf8' }, (error, stdout, stderr) => {
// console.log(error);
if (error) {
console.log('报错了');
return;
}
console.log(`stderr:${stderr}`);
console.log(`stdout:${stdout}`);
});
*/
/*
三个参数:
1. shell 头
2. 数组 shell 后面
3. 配置项
*/
const ls = spawn('ls', ['-a'], {
encoding: 'utf8',
shell: true,
cwd: undefined,
env: process.env,
});
ls.stdout.on('data', (data) => {
console.log(`stdout:${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr:${data}`);
});
ls.on('close', (code) => {
console.log(`close:${code}`);
});
cluster 模块
协助开发者利用 CPU。
正常情况下,Node 只能利用 CPU 中的某一个内核,就会产生一些资源利用上的浪费,利用该模块就能充分利用 CPU 的资源。
PID( 进程控制符 )英文全称为Process Identifier,它也属于 电工电子 类技术术语。 PID是各进程的代号,每个进程有唯一的PID编号。 它是进程运行时系统分配的,并不代表专门的进程。 在运行时PID是不会改变标识符的,但是进程终止后PID标识符就会被系统回收,就可能会被继续分配给新运行的程序。
const cluster = require('cluster');
const http = require('http');
const os = require('os');
const cpus = os.cpus().length;
// console.log(cpus);
if (cluster.isMaster) {
console.log(`主进程:${process.pid}已经启动`);
//衍生工作进程
for (let index = 0; index < cpus; index++) {
cluster.fork();
}
} else {
//工作进程可以共享任何 tcp 连接
//这里共享的是 http 的服务器
http
.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'text/html;charset=utf-8',
});
res.write('hello');
res.end();
})
.listen(8000);
console.log(`工作进程${process.pid}已经启动`);
}
master 进程与 cluster 进程的通信
master.js
const { fork } = require('child_process');
const child = fork('./child.js');
child.on('message', (msg) => {
console.log(`来自子进程:${msg}`);
});
child.send('来自master');
child.js
console.log(`子进程${process.pid}`);
process.on('message', (msg) => {
console.log(`来自master:${msg}`);
});
process.send('这是子进程');