一文聊聊node的多进程和多线程
node.js中的多进程与多线程
在node.js中,javascript代码的执行是单线程执行的,可是Node 本身其实是多线程的。
node本身分为三层
第一层,Node.js 标准库,这部分是由 Javascript编写的,即我们使用过程中直接能调用的 API,在源码中的 lib 目录下可以看到。
第二层,Node bindings,这一层是 Javascript 与底层 C/C++ 能够沟通的关键,前者通过 bindings 调用后者,相互交换数据,是第一层和第三层的桥梁。
第三层,是支撑 Node.js 运行的关键,由 C/C++ 实现,是node实现的一些底层逻辑。
其中,第三层的Libuv,为 Node.js 提供了跨平台,线程池,事件池,异步 I/O 等能力,是 Node.js 如此强大的关键。
由于Libuv提供了事件循环机制,所以在io处理方面,javascript并不会发生阻塞,所以我们用node搭建web服务时,并不需要担心io量过大,导致其他请求阻塞。
可是,非io任务的执行,是在node主线程中执行的,是单线程执行任务,如果有非常消耗时间的同步计算任务,将会阻塞其他代码的执行。
const Koa = require('koa'); const app = new Koa(); app.use(async (ctx) => { const url = ctx.request.url; if (url === '/') { ctx.body = { name: 'xxx', age: 14} } if(url==='/compute'){ let sum=0 for (let i = 0; i 100000000000 ; i++) { sum+=i } ctx.body={ sum} } } )app.listen(4000, () => { console.LOG('http://localhost:4000/ start')} )
上面这串代码,如果http请求了 /compute
,node会调用cpu进行大量的计算,这时如果有其他http请求进入,将会发生阻塞。
那么如何解决这个问题呢?
有两种方案,一种是使用children_PRocess
或者cluster
开启多进程进行计算,一种是使用worker_thread
开启多线程进行计算
多进程 vs 多线程
对比一下多线程与多进程:
属性 | 多进程 | 多线程 | 比较 |
---|---|---|---|
数据 | 数据共享复杂,需要用IPC;数据是分开的,同步简单 | 因为共享进程数据,数据共享简单,同步复杂 | 各有千秋 |
CPU、内存 | 占用内存多,切换复杂,CPU利用率低 | 占用内存少,切换简单,CPU利用率高 | 多线程更好 |
销毁、切换 | 创建销毁、切换复杂,速度慢 | 创建销毁、切换简单,速度很快 | 多线程更好 |
coding | 编码简单、调试方便 | 编码、调试复杂 | 编码、调试复杂 |
可靠性 | 进程独立运行,不会相互影响 | 线程同呼吸共命运 | 多进程更好 |
分布式 | 可用于多机多核分布式,易于扩展 | 只能用于多核分布式 | 多进程更好 |
采用多线程来解决上面代码的计算问题:
//api.jsconst Koa = require('koa'); const app = new Koa(); const { Worker} = require('worker_threads')app.use(async (ctx) => { const url = ctx.request.url; if (url === '/') { ctx.body = { name: 'xxx', age: 14} } if (url === '/compute') { const sum = await new Promise(resolve => { const worker = new Worker(__dirname+'/compute.js') //接收信息 worker.on('message', data => { resolve(data) } ) } ) ctx.body = { sum} } } )app.listen(4000, () => { console.log('http://localhost:4000/ start')} )//computer.jsconst { parentPort} =require('worker_threads')let sum=0for (let i = 0; i 1000000000 ; i++) { sum+=i} //发送信息parentPort.postMessage(sum)
这里是官方文档,worker_threads
https://nodejs.org/dist/latest-v16.x/docs/api/worker_threads.htML
采用多进程来解决上面代码的计算问题:
//api.jsconst Koa = require('koa'); const app = new Koa(); const { fork} = require('child_process')app.use(async (ctx) => { const url = ctx.request.url; if (url === '/') { ctx.body = { name: 'xxx', age: 14} } if (url === '/compute') { const sum = awaIT new Promise(resolve => { const worker =fork(__dirname+'/compute.js') worker.on('message', data => { resolve(data) } ) } ) ctx.body = { sum} } } )app.listen(4000, () => { console.log('http://localhost:4000/ start')} )//computer.jslet sum=0for (let i = 0; i 1000000000 ; i++) { sum+=i} process.send(sum)
这里是官方文档,child_process
https://nodejs.org/dist/latest-v16.x/docs/api/child_process.html
更多node相关知识,请访问:nodejs 教程!
以上就是一文聊聊node的多进程和多线程的详细内容,更多请关注其它相关文章!
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 一文聊聊node的多进程和多线程
本文地址: https://pptw.com/jishu/593716.html