亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Nodejs事件循環

Nodejs事件循環

鳳凰求蠱 2019-07-31 14:38:36
Nodejs事件循環nodejs架構內部有兩個事件循環嗎?libev / libuvv8 javascript事件循環在I / O請求上,節點將請求排隊到libeio,后者又通過使用libev的事件通知數據的可用性,最后這些事件是由v8事件循環使用回調來處理的嗎?基本上,libev和libeio如何集成在nodejs架構中?有沒有可用于提供nodejs內部架構清晰圖片的文檔?
查看完整描述

3 回答

?
喵喵時光機

TA貢獻1846條經驗 獲得超7個贊

看起來所討論的一些實體(例如:libev等)已經失去了相關性,因為它已經有一段時間了,但我認為這個問題仍然具有很大的潛力。

讓我嘗試在抽象的UNIX環境中,在Node的上下文中,借助抽象示例來解釋事件驅動模型的工作。

計劃的觀點:

  • 腳本引擎開始執行腳本。

  • 每當遇到CPU綁定操作時,它都會在內聯(真實機器)中完成。

  • 每當遇到I / O綁定操作時,請求及其完成處理程序都會在“事件機器”(虛擬機)中注冊

  • 以相同的方式重復操作,直到腳本結束。CPU綁定操作 - 執行內聯,I / O綁定操作,如上所述向機器請求。

  • 當I / O完成時,將回調一下監聽器。

上面的事件機制稱為libuv AKA事件循環框架。Node利用此庫來實現其事件驅動的編程模型。

Node的觀點:

  • 有一個線程來托管運行時。

  • 拿起用戶腳本。

  • 將其編譯為本機[杠桿v8]

  • 加載二進制文件,然后跳轉到入口點。

  • 已編譯的代碼使用編程原語在線執行CPU綁定活動。

  • 許多I / O和計時器相關的代碼都有本機包裝。例如,網絡I / O.

  • 因此,I / O調用從腳本路由到C ++橋接器,I / O句柄和完成處理程序作為參數傳遞。

  • 本機代碼執行libuv循環。它獲取循環,將表示I / O的低級事件排入隊列,并將本機回調包裝器排入libuv循環結構。

  • 本機代碼返回到腳本 - 此刻不會發生I / O!

  • 上面的項目重復多次,直到執行所有非I / O代碼,并且所有I / O代碼都被注冊到libuv。

  • 最后,當系統中沒有任何內容要執行時,節點將控制權傳遞給libuv

  • libuv開始行動,它獲取所有已注冊的事件,查詢操作系統以獲得其可操作性。

  • 在非阻塞模式下準備好I / O的那些被拾取,執行I / O,并且發出它們的回調。一個接一個地。

  • 尚未準備好的那些(例如套接字讀取,另一個端點尚未寫入任何內容)將繼續用OS進行探測,直到它們可用。

  • 循環內部維持一個不斷增加的計時器。當應用程序請求延遲回調(例如setTimeout)時,將利用此內部計時器值來計算觸發回調的正確時間。

雖然大多數功能都以這種方式迎合,但文件操作的一些(異步版本)是在附加線程的幫助下執行的,并且很好地集成到libuv中。雖然網絡I / O操作可以等待期望外部事件,例如另一個端點響應數據等,但文件操作需要來自節點本身的一些工作。例如,如果你打開一個文件并等待fd準備好數據,它就不會發生,因為沒有人正在閱讀!同時,如果您從主線程中的內聯文件中讀取,它可能會阻止程序中的其他活動,并且可能會產生可見問題,因為與cpu綁定活動相比,文件操作非常慢。因此,內部工作線程(可通過UV_THREADPOOL_SIZE環境變量配置)用于對文件進行操作,

希望這可以幫助。


查看完整回答
反對 回復 2019-07-31
?
眼眸繁星

TA貢獻1873條經驗 獲得超9個贊

ibuv簡介

該Node.js的項目開始于2009年從瀏覽器分離一個JavaScript環境。使用谷歌的V8和Marc Lehmann的libev,node.js將I / O模型 - 偶數 - 與一種非常適合編程風格的語言相結合; 由于瀏覽器的形成方式。隨著node.js越來越流行,讓它在Windows上運行很重要,但libev只能在Unix上運行。Windows等效的內核事件通知機制(如kqueue或(e)輪詢)是IOCP。libuv是一個圍繞libev或IOCP的抽象,取決于平臺,為用戶提供基于libev的API。在node-v0.9.0版本的libuv中,libev被刪除了。

還有一張用@ BusyRich描述Node.js中的事件循環的圖片

根據這個doc Node.js事件循環,


下圖顯示了事件循環操作順序的簡要概述。



   ┌───────────────────────┐

┌─>│        timers         │

│  └──────────┬────────────┘

│  ┌──────────┴────────────┐

│  │     I/O callbacks     │

│  └──────────┬────────────┘

│  ┌──────────┴────────────┐

│  │     idle, prepare     │

│  └──────────┬────────────┘      ┌───────────────┐

│  ┌──────────┴────────────┐      │   incoming:   │

│  │         poll          │<─────┤  connections, │

│  └──────────┬────────────┘      │   data, etc.  │

│  ┌──────────┴────────────┐      └───────────────┘

│  │        check          │

│  └──────────┬────────────┘

│  ┌──────────┴────────────┐

└──┤    close callbacks    │

   └───────────────────────┘


注意:每個框將被稱為事件循環的“階段”。


階段概述


定時器:此階段執行由setTimeout()和調度的回調setInterval()。

I / O回調:除了執行幾乎所有回調之外

關閉回調,由計時器安排的回調,和setImmediate()??臻e,準備:僅在內部使用。

poll:檢索新的I / O事件; 節點將在適當時阻止此處。

check:setImmediate()在這里調用回調。

關閉回調:例如socket.on('close', ...)。

在事件循環的每次運行之間,Node.js檢查它是否在等待任何異步I / O或定時器,如果沒有,則檢查是否干凈。


查看完整回答
反對 回復 2019-07-31
  • 3 回答
  • 0 關注
  • 760 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號