我们在电脑中会运行多个程序,每一个程序中都会有多个线程。
例如我们运行比特币客户端的时候,我们某一个线程要处理网络、某一个线程要处理挖矿、某一个线程要处理用户输入…
线程的调度使用了操作系统级别的调度器来明确了哪一个线程应该被执行。线程也有优先级之分,例如监听鼠标滑动的优先级就会很高,因为其不能等待太长的时间。
为了在给定的时间内更快更多的处理线程:
1、我们可以通过增加CPU的核心数量或者是
2、调度器当监测到线程中运行中断,如读取文件网络时,及时切换到其他的线程中执行。
nodejs是单线程的事件循环机制
伪代码演示事件循环:
123456789101112131415161718192021222324 | const peningTimers =[];const pendingOSTasks=[];cosnt pendingOperations=[];1、初始化myfile.runContent()function shouldContinue(){ //是否继续 1、检查setTimeOut、setInterval、setImmediate 2、检查是否有监听端口等操作系统级别的任务 3、检查是否有文件、网络等长期的操作return peningTimers.length || pendingOSTasks.length || pendingOperations.length;}2、事件循环while(shouldContinue()){//1.观察peningTimers.length,是否调查setTimeOut、setInterval等函数//2、观察pendingOSTasks.length pendingOperations.length,并调用相关回调函数//3.暂停、一直等到上面的某一个事件完成//4、调用setImmediate等函数//5、处理close事件}3、退出 |
nodejs的单线程,是对于其处理事件循环来讲的,有了事件触发,就会执行相应函数。没有事件触发,就会等待。从这个意义上来说,nodejs是单线程的。
但是在处理具体的任务,函数的时候。nodejs确是多线程的。
1234567 | const crypto = require('crypto');const start = Date.now();crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('1:',Date.now()-start);}); |
测试pbkdf2速度:1: 868
1234567891011 | const crypto = require('crypto');const start = Date.now();crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('1:',Date.now()-start);});crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('2:',Date.now()-start);}); |
测试pbkdf2速度:
12 | 1: 8912: 893 |
说明了pbkdf2函数是多线程来执行的。libuv中默认有4个线程,pbkdf2函数正是借助libuv实现了多线程。
12345678910111213141516171819 | const crypto = require('crypto');const start = Date.now();crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('1:',Date.now()-start);});crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('2:',Date.now()-start);});crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('3:',Date.now()-start);});crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('4:',Date.now()-start);});crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('5:',Date.now()-start);}); |
12345 | 4: 9191: 9223: 9362: 9365: 1813 |
注意,明显第5个线程时间增加了一倍,因为默认libuv中默认有4个线程,第5个线程陷入了等待。
123456789101112131415161718192021 | process.env.UV_THREADPOOL_SIZE = 5;const crypto = require('crypto');const start = Date.now();crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('1:',Date.now()-start);});crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('2:',Date.now()-start);});crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('3:',Date.now()-start);});crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('4:',Date.now()-start);});crypto.pbkdf2('a','b',100000,512,'sha512',()=>{ console.log('5:',Date.now()-start);}); |
测试速度:
12345 | 1: 9565: 9633: 9702: 9714: 974 |
123456789101112131415161718192021 | const https = require('https');const start = Date.now();function dorequest(){ https.request('https://www.baidu.com',res=>{ res.on('data',()=>{}); res.on('end',()=>{ console.log(Date.now()-start); }); }) .end();}dorequest();dorequest();dorequest();dorequest();dorequest();dorequest();dorequest();dorequest();dorequest(); |
测试速度:
123456789 | 485052535455575862 |
https网络访问,调用了操作系统资源,libuv只是起到了代理的作用,所以不收到libuv默认4个线程的限制。
本文链接: https://dreamerjonson.com/2018/11/09/深度理解nodejs-2/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。