資源描述:
《關(guān)于nodejs的誤會》由會員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫。
1、昨天寫了篇博客,介紹了一下我對node.js的第一次親密接觸后的感受,以為node.js很小眾,出乎我意料很多人感興趣,并且對博客中的細(xì)節(jié)問題做了評論,最多的是圍繞node.js的界步與單線程展開的,當(dāng)然還有很多關(guān)Vnode.js究竟是不是語言?不是的話又是什么。。。Z類的問題,其實剛接觸node.js,了解的并不是很深入,越是回復(fù)大家問題,心里越是沒底,決定認(rèn)真研究一下,經(jīng)人指點看了一下《Node.js開發(fā)指南》發(fā)現(xiàn)人部分問題都有了答案,權(quán)當(dāng)一個讀書筆記把問題答案分享出來,希望可以幫到一些和我一樣才接觸node.js的小菜關(guān)于單線程一個由來已久的誤會在上篇博客中提到我們
2、使用node.js寫的JavaScript代碼是單線程運(yùn)行的,讓很多同學(xué)很疑惑,單線程怎么實現(xiàn)異步操作,單線程誰去響應(yīng)事件。。。在html5WebWorkers小我也有提到過客戶端的JavaScript也是單線程運(yùn)行的,人家明顯沒有這么人反應(yīng),還是普遍能接受的??蓡尉€程的客戶端JavaScript也能響應(yīng)DOM事件,還有大家都很熟悉的ajax操作,回調(diào)函數(shù)也是界步的,既然客八端JavaScript是單線程執(zhí)行的,回調(diào)函數(shù)是誰調(diào)用的呢?答案很簡單,JavaScript的宿主環(huán)境——瀏覽器,也就是說雖然JavaScript是單線程執(zhí)行的,但瀏覽器是多線程的,負(fù)責(zé)調(diào)度管理Jav
3、aScript代碼,讓它們在恰當(dāng)?shù)臅r機(jī)執(zhí)行。所以我們所說的node.js單線程,是指node.js并沒有給我們創(chuàng)建一個線程的能力,所有-我們口己寫的代碼都是單線程執(zhí)行的,在同一時間內(nèi),只能執(zhí)行我們寫的一句代碼。但宿主環(huán)境node.js并不是單線程的,它會維護(hù)一個執(zhí)行隊列,循環(huán)檢測,調(diào)度JavaScript線程來執(zhí)行。因此單線程執(zhí)行和并發(fā)操作并不沖突。阻塞與線程什么叫阻塞(block)?線程在執(zhí)彳亍屮如果遇到I/O操作(磁盤讀寫、網(wǎng)絡(luò)通信等)通常需要耗費(fèi)較長的時間,這時候操作系統(tǒng)會剝奪線程對CPU的控制權(quán),使其暫停,并把資源讓給其它的工作線程,這種線程調(diào)度方式成為阻塞。當(dāng)I
4、/O操作完畢的時候操作系統(tǒng)將這個線程的阻塞狀態(tài)解除,恢復(fù)其對CPU的控制權(quán),令其繼續(xù)執(zhí)行,這種I/O模式就是同步I/O或成為阻塞I/0o響應(yīng)的異步I/O或非阻塞I/O則針對所有的I/O操作采取不阻塞的策略,當(dāng)線程遇到I/O操作時不會以阻塞的方式等待I/O操作結(jié)束,而只是將I/O請求發(fā)送給操作系統(tǒng),繼續(xù)執(zhí)行后續(xù)語句。當(dāng)操作系統(tǒng)完成I/O操作時以事件的形式通知執(zhí)行I/O操作的線程,線程會在特定時間處理這個事件。為了處理片步I/O必須有事件循環(huán),不斷檢查有沒有未處理的事件,依次了以處理。在阻塞模式下,一個線程只能處理一個任務(wù),要想提高吞吐量必須通過多線程。而在非阻塞模式下一個線
5、程永遠(yuǎn)在執(zhí)行計算操作,這個線程所使用的CPU核心利用率永遠(yuǎn)是100%,I/O以事件的方式通知。在阻塞模式下多線程往往能夠提高系統(tǒng)吞吐量,因為一個線程阻塞時還有其他線程在工作,多線程何以讓CPU資源不被阻塞的線程浪費(fèi)。而在非阻塞模式下,線程不會被I/O阻塞,永遠(yuǎn)在利用CPU。異步I/O減少了多線程屮創(chuàng)建線程、分配內(nèi)存、列入調(diào)度、切換線程、內(nèi)存換頁、CPU緩存等方面的開銷。事件循環(huán)機(jī)制上而提到了幾次事件循壞機(jī)制,那么這個聽起來貌似很高端的東東究竟是什么呢?所謂事件循環(huán)是指node.js會把所有的異步操作使用事件機(jī)制解決,有個線程在不斷地循環(huán)檢測事件隊列。node.js中所有的
6、邏輯都是事件的回調(diào)函數(shù),所以node.js始終在事件循環(huán)中,程序入口就是事件循環(huán)第一個事件的冋調(diào)函數(shù)。事件的冋調(diào)函數(shù)屮可能會發(fā)出I/O請求或肓接發(fā)射(emit)事件,執(zhí)行完畢示返回事件循環(huán)。事件循環(huán)會檢杏事件隊列屮有沒有未處理的事件,直到程序結(jié)束。node.js的事件循環(huán)對開發(fā)者不可見,由libev庫實現(xiàn),libev不斷檢查是否有活動的、可供檢測的事件監(jiān)聽器,直到檢查不到時才追岀事件循環(huán),程序結(jié)束。node.js是什么?和JavaScript有什么關(guān)系?關(guān)于node.js究竟是什么,大家的問題在于1.node.js是不是一門語言?2.node.js是不是一個JavaScr
7、ipt庫函數(shù)?3.node.js是不是一個JavaScript框架?很遺憾,這三個問題的答案都是NO,看看官方對口己的描述Node.jsisaplatformbuiltonChrome'sJavaScriptruntimeforeasilybuildingfast,scalablenetworkapplications.Node.jsusesanevent?driven,non?blockingI/Omodelthatmakesitlightweightandefficient,perfectfordata-intensive