Nodejs自己說是是單線程并且實(shí)現(xiàn)異步IO操作,只看上一句話就知道肯定是扯淡;那這個(gè)家伙是怎么實(shí)現(xiàn)的呢?
最底層,支持Nodejs運(yùn)行的關(guān)鍵: V8 引擎:用來解析、執(zhí)行javascript代碼的運(yùn)行環(huán)境。 libuv: 提供最底層的IO操作接口,包括文件異步IO的線程池管理和網(wǎng)絡(luò)的IO操作,是整個(gè)異步IO實(shí)現(xiàn)的核心!這部分由C/C++編寫,在源碼的deps目錄下可以看到。
正是這部分,Nodejs中許多異步方法在具體的實(shí)現(xiàn)時(shí)(NodeJs底層封裝了Libuv,它提供了線程池、事件池、異步I/O等模塊功能,其完成了異步方法的具體實(shí)現(xiàn)),內(nèi)部均采用了多線程機(jī)制。
但是,只有用戶的js代碼全部執(zhí)行完后,nodejs才調(diào)用libuv的事件循環(huán)入口函數(shù)uv_run(),即回調(diào)函數(shù)才有可能被執(zhí)行。所以,如果主線程的js代碼調(diào)用了阻塞方法,那么整個(gè)事件輪詢就會(huì)被阻塞,事件隊(duì)列中的事件便得不到及時(shí)處理
不適合CPU密集型應(yīng)用;因?yàn)榇藭r(shí)CPU會(huì)被長(zhǎng)時(shí)間占用,被阻塞的線程會(huì)全部無法處理。將會(huì)導(dǎo)致CPU時(shí)間片不能釋放,使得后續(xù)I/O無法發(fā)起;
結(jié)論:
1.node適合做I/O密集型,密集的意思是一個(gè)請(qǐng)求里有多個(gè)并行的i/o,并不是這個(gè)系統(tǒng)大部分是I/O請(qǐng)求
2.由于node主方法是單線程,所以除了I/O外的代碼量越少越好,否則將失去意義
2.由于node主方法是單線程,所以除了I/O外的代碼量越少越好,否則將失去意義