此章节一共分为两个章节,下一节,nodejs-第二章-第三节-nodejs多进程-cluster(2-2)node
- 进程是资源分配的最小单位,线程是CPU调度的最小单位
- 进程--资源分配最小单位,线程--程序咨询最小单位
一个进程下面的线程是能够去通讯的,共享资源算法
多进程和多线程通常能够结合起来使用shell
对比维度 | 多进程 | 多线程 | 总结 |
---|---|---|---|
数据共享、同步 | 数据共享复杂,须要用IPC;数据是分开的,同步简单 | 由于共享进程数据,数据共享简单,但也是由于这个致使同步复杂 | 各有优点 |
内存、cpu | 占用内存多,切换负责,cpu利用率低 | 占用内存少,切换简单,cpu利用率高 | 线程占优 |
建立销毁、切换 | 建立销毁复杂,速度慢 | 建立销毁简单,速度很快 | 线程占优 |
编程、调试 | 编程简单,调试简单 | 编程复杂、调试复杂 | 进程占优 |
可靠性 | 进程间不会相互影响 | 一个线程挂掉将致使整个进程挂掉 | 进程占优 |
分布式 | 适应于多核、多机分布式;若是一台机器不够,扩展到多台机器比较简单 | 适应于多核分布式 | 进程占优 |
利用cluster开启多进程apache
const cluster = require('cluster'); // 多进程 const http = require('http'); const numCpus = require('os').cpus().length; // 获取cpu的核数 if(cluster.isMaster){ // 是不是主线程 for(var i = 0; i < numCpus; i++){ cluster.fork() // 开启子线程 cluster.on('exit', function(worker, code ,signal){ // 监测哪一个进程挂掉 console.log('worker'+worker.process.pid+'died') }) } } else { http.createServer((req,res) =>{ res.writeHead(200); res.end('hello world'); }).listen(8000) }
多进程的性能要明显好于单进程编程
Process进程,child_process子进程,Cluster集群json
process对象是Node的一个全局对象,提供当前Node进程的信息,它也能够在脚本的任意位置使用,没必要经过require获取;数组
属性浏览器
方法安全
事件bash
bbb() // 这里会直接报错,由于js是单线程的, // uncaughtException专门是捕捉异步代码错误,特别是http process.on('uncaughtException', (err) =>{ console.log(err) })
const http = require('http'); http.createServer((req, res) => { ccc() }).listen(8000, () => { console.log(`server is runing on 8000`) }) process.on('uncaghtException', (err) => { // 这里会捕获ccc的异步错误s console.log('发生错误',err) })
node中用于建立子进程的模块,cluster就是基于child_process模块封装的;
const exec = require('child_process').exec; // 1. 经过回调的方式接收结果 // exec('ls', (err, stdout, stderr) => { // // 在node中,容错处理和业务代码同样重要; // // 由于js是单线程,一旦发生错误,后面代码就不会执行 // if (err) { // console.log('stderr', stderr); // } // console.log('err', err); // console.log('stdout', stdout); // }); // 因为标准输出和标准错误都是流对象(stream),能够监听data事件 // 2. 经过流的方式返回结果, // 能够一边读取一边接收结果,不用等全部文件读取完 var child = exec('lss'); child.stdout.on('data', data => { console.log(data); }); // 发生错误 child.stderr.on('data', err => { console.log('发生错误了', err); }); console.log(111)
var execSync('child_progress'); var path = '../' var child = execSync(`ls ${path} \ rm rf`); // 这样会删除此文件夹的上一级目录的全部文件 console.log(child.toString());
const { execFile } = require('child_progress') execFile('ls', ['-c'], (err, stdout, stderr) => { console.log('stdout', stdout) })
const { spawn } = require('child_process'); let child = spawn('ls', ['-c']); child.stdout.on('data', data => { console.log('data', data.toString('utf8')); });
main.js
const child_process = require('child_process'); const path = require('path'); var child = child_process.fork(path.resolve(__dirname, './child.js')); child.on('message', data => { console.log('父接收到子消息:', data); }); child.send('父亲send', data => { console.log('父亲说:为父给你发消息了'); });
child.js
process.on('message', data => { console.log('儿子接收到父亲消息:', data); }); process.send('儿子send', data => { console.log('儿子对父亲说:hello '); });