JS无论在浏览器还是Node环境中都是单线程的,但可以通过调用API开启多进程提高硬件资源利用率。
以下介绍在nodejs中开启多进程并实现通信的方式。
进程 vs 线程
进程:资源分配
的最小单位
线程:CPU调度
的最小单位
开启子进程方式
- child_process.fork
- cluster.fork
通信方式
使用send和on传递消息
两种方式的使用场景
child_process.fork:使用于开启单个计算,完成计算量比较大的工作
cluster:集成,适用多个进程开启多个网络服务的场景
代码
方式一: child_process.fork
主进程process.js
const http = require('http')
const fork = require('child_process').fork
const server = http.createServer((req, res) => {
if (req.url == "/get-sum") {
console.log('主进程id', process.pid);
// 开启子进程
const computedProcess = fork('./computed.js')
computedProcess.send('开始计算')
computedProcess.on('message', data => {
console.log('主进程收到的信息', data);
res.end('sum is ' + data)
})
computedProcess.on('close', () => {
console.log('子进程因报错而退出')
computedProcess.kill()
res.end('error')
})
}
})
server.listen(3000, () => {
console.log('http://localhost:3000');
})
子进程 computed.js
function getSum() {
let sum = 0
for (let i = 0; i < 10000; i++) {
sum += i
}
return sum
}
process.on('message', data => {
console.log('子进程id', process.pid);
console.log('子进程接受到的信息', data);
const sum = getSum()
// 发送消息给主进程
process.send(sum)
})
方式二:cluster.fork
const http = require('http')
const cpuCoreLength = require('os').cpus().length
const cluster = require('cluster')
if (cluster.isMaster) {
for (let i = 0; i < cpuCoreLength; i++) {
cluster.fork() // 开启子进程
}
cluster.on('exit', worker => {
console.log('子进程退出');
cluster.fork() // 进程守护
})
} else {
// 多个子进程会共享一个TCP连接,提供一份网络服务
const server = http.createServer((req, res) => {
res.writeHead(200)
res.end('done')
})
server.listen(3000)
}
// 工作中 PM2