排除用戶體驗的因素,我們從資源分配的層面來分析一下異步I/O的必要性。我們直到計算機在發展過程中將組件進行了抽象,分為I/O設備和計算設備。
假設業務場景中有一組互不相關的任務需要完成,現在的主流方法有以下兩種:
* 單線程串行依次執行
* 多線程并行完成
如果創建多線程的開銷小于并行執行,那么多線程的方式是首選的。多線程的代價在于創建線程和執行期線程上下文切換的開銷較大。另外,在復雜的業務中,多線程編程經常面臨鎖、狀態同步等問題,這是多線程被詬病的主要原因。但是多線程在多核CPU上能夠有效提升CPU的利用率,這個優勢是毋庸置疑的。
單線程順序執行任務的方式比較符合編程人員按順序思考的思維方式。它依然是主流的編程方式,因為它易于表達。但是串行執行的缺點在于性能,任意一個略慢的任務都會導致后續執行代碼被阻塞。在計算機資源中,通常I/O和CPU計算之間是可以并行進行的。但是同步的編程模型導致的問題是,I/O的進行會讓后續任務等待,這造成資源不能被更好利用。
操作系統會將CPU的時間片分配給其余進程,以公平而有效的利用資源,基于這一點,有的服務器為了提升響應能力,會通過啟動多個工作進程來為更多的用戶服務。但是對于這一組任務而言,它無法分發任務到多個進程上,所以依然無法高效利用資源,結束所有任務所需的時間將會較長。這種模式類似于加三倍服務器,達到占用更多資源來提升服務速度,它并沒有真正改善問題。
添加硬件資源是一種提升服務質量的方式,但它不是唯一方式。
單線程同步編程模型會阻塞I/O導致硬件資源得不到更優的使用。多線程編程模型也因為編程中的死鎖、狀態同步等問題讓開發人員頭疼。
Node在兩者之間給出了它的方案:利用單線程,遠離多線程死鎖、狀態同步等問題;利用異步I/O,讓單線程遠離阻塞,以更好的利用CPU。
異步I/O可以算作Node的特色,因為它是首個大規模將異步I/O應用在應用層上的平臺,它力求在單線程上將資源分配的更高效。
為了彌補單線程無法利用多核CPU的缺點,Node提供了類似前端瀏覽器中Web worker的子進程,該子進程可以通過工作進程高效的利用CPU和I/O。這部分內容將在第9章中詳述。
異步I/O的提出是期望I/O調用不再阻塞后續運算,將原有等待I/O完成的這段時間分配給其它需要的業務去執行。
下圖為異步調用I/O示意圖:

- 目錄
- 第1章 Node 簡介
- 1.1 Node 的誕生歷程
- 1.2 Node 的命名與起源
- 1.2.1 為什么是 JavaScript
- 1.2.2 為什么叫 Node
- 1.3 Node給JavaScript帶來的意義
- 1.4 Node 的特點
- 1.4.1 異步 I/O
- 1.4.2 事件與回調函數
- 1.4.3 單線程
- 1.4.4 跨平臺
- 1.5 Node 的應用場景
- 1.5.1 I/O 密集型
- 1.5.2 是否不擅長CPU密集型業務
- 1.5.3 與遺留系統和平共處
- 1.5.4 分布式應用
- 1.6 Node 的使用者
- 1.7 參考資源
- 第2章 模塊機制
- 2.1 CommonJS 規范
- 2.1.1 CommonJS 的出發點
- 2.1.2 CommonJS 的模塊規范
- 2.2 Node 的模塊實現
- 2.2.1 優先從緩存加載
- 2.2.2 路徑分析和文件定位
- 2.2.3 模塊編譯
- 2.3 核心模塊
- 2.3.1 JavaScript核心模塊的編譯過程
- 2.3.2 C/C++核心模塊的編譯過程
- 2.3.3 核心模塊的引入流程
- 2.3.4 編寫核心模塊
- 2.4 C/C++擴展模塊
- 2.4.1 前提條件
- 2.4.2 C/C++擴展模塊的編寫
- 2.4.3 C/C++擴展模塊的編譯
- 2.4.2 C/C++擴展模塊的加載
- 2.5 模塊調用棧
- 2.6 包與NPM
- 2.6.1 包結構
- 2.6.2 包描述文件與NPM
- 2.6.3 NPM常用功能
- 2.6.4 局域NPM
- 2.6.5 NPM潛在問題
- 2.7 前后端共用模塊
- 2.7.1 模塊的側重點
- 2.7.2 AMD規范
- 2.7.3 CMD規范
- 2.7.4 兼容多種模塊規范
- 2.8 總結
- 2.9 參考資源
- 第3章 異步I/O
- 3.1 為什么要異步I/O
- 3.1.1 用戶體驗
- 3.1.2 資源分配
- 3.2 異步I/O實現現狀
- 3.2.1 異步I/O與非阻塞I/O
- 3.2.2 理想的非阻塞異步I/O
- 3.2.3 現實的異步I/O
- 3.3 Node的異步I/O
- 3.3.1 事件循環
- 3.3.2 觀察者
- 3.3.3 請求對象
- 3.3.4 執行回調
- 3.3.5 小結
- 3.4 非I/O的異步API
- 3.4.1 定時器
- 3.5 事件驅動與高性能服務器