站長資訊網
        最全最豐富的資訊網站

        帶你了解Nodejs中的非阻塞異步IO

        本篇文章帶大家聊聊Node中的各種I/O模型,介紹一下Node的靈魂—非阻塞異步IO,希望對大家有所幫助!

        帶你了解Nodejs中的非阻塞異步IO

        node.js極速入門課程:進入學習

        【相關教程推薦:nodejs視頻教程、編程教學】

        我們以網絡請求IO為例,首先介紹服務端處理一次完整的網絡IO請求的典型流程:

        帶你了解Nodejs中的非阻塞異步IO

        應用程序獲得一個操作結果,通常包括兩個不同的階段:

        • 等待數據準備好

        • 從內核向進程復制數據

        以下,我們以 recvfrom 函數為例,解釋說明各種IO模型

        阻塞式 I/O 模型(blocking I/O)

        阻塞調用是指調用結果返回之前,當前線程會被掛起,調用線程只有在等待系統內核層面所有操作完成之后,調用才會結束。

        阻塞I/O造成了cpu的等待I/O,浪費了CPU的時間片。

        帶你了解Nodejs中的非阻塞異步IO

        非阻塞式I/O模型(non-blocking I/O)

        相比于前者,非阻塞I/O不帶數據直接返回,要獲取數據,還需要通過文件描述符再次嘗試讀取數據

        帶你了解Nodejs中的非阻塞異步IO

        阻塞調用得到返回(并不是真實的期待數據)之后,CPU時間片可以用于處理其他的事情,可以明顯提升性能。

        但是隨之而來的問題是,之前的操作并不是一次完整的I/O,返回得到的結果不是期望得到的業務數據,而僅僅是異步調用狀態。

        為了獲取完整的數據,應用程序需要重復調用IO操作來確認操作是否已經完成,這種操作我們稱之為輪詢,常見的幾種輪詢策略如下

        忙輪詢

        這是最原始,也是性能最低的一種方式,通過重復調用來檢查I/O狀態達到獲取完整數據的目的

        帶你了解Nodejs中的非阻塞異步IO

        優點:編程簡單

        缺點:CPU一直耗費在輪詢上,同時影響服務器性能,因為你輪詢之后服務器還要進行作答

        I/O復用模型(I/O multiplexing)

        帶你了解Nodejs中的非阻塞異步IO

        在 I/O 復用模型中,會用到 Select 或 Poll 函數或 Epoll 函數(Linux 2.6 以后的內核開始支持),這兩個函數也會使進程阻塞,但是和阻塞 I/O 有所不同。

        這三個函數可以同時阻塞多個 I/O 操作,而且可以同時對多個讀操作,多個寫操作的 I/O 函數進行檢測,直到有數據可讀或可寫時,才真正調用 I/O 操作函數。

        三種I/O復用機制的區別如下

        • select

        由于select采用1024長度的數組來存儲文件狀態,因此最多可以同時檢測1024個文件描述符

        • poll

        相比select略有改進,采用鏈表避免了1024的長度限制,并且能避免不需要的遍歷檢查,相比select性能稍有改善

        • epoll/kqueue

        是linux下效率最高的I/O事件通知機制,輪詢時如果沒有檢測到I/O事件,將會進行休眠,直到事件發生將線程喚醒。它是真正利用了事件通知,執行回調,而不是遍歷(文件描述符)查詢,因此不會浪費CPU

        帶你了解Nodejs中的非阻塞異步IO

        小結:本質上說,輪詢仍然是一種同步操作,因為應用程序仍然在等待I/O完全返回,等待期間要么遍歷文件描述狀態,要么休眠等待事件的發生。

        信號驅動式I/O模型(signal-driven I/O)

        帶你了解Nodejs中的非阻塞異步IO

        在信號驅動式 I/O 模型中,應用程序使用信號驅動 I/O,并安裝一個信號處理函數,進程繼續運行并不阻塞。

        當數據準備好時,程序會收到一個 SIGIO 信號,可以在信號處理函數中調用 I/O 操作函數處理數據。

        小結:到此為止,信號驅動式I/O模型是更加符合我們的異步需求的,程序會在等待數據的過程中異步執行其他的業務邏輯。

        但是!!! 在數據從內核復制到用戶空間過程中依然是阻塞的,并不能算是一場徹底的革命(異步)。

        理想中的(Node)非阻塞異步I/O

        我們理想中的異步I/O應該是應用程序發起非阻塞調用,無需通過輪詢的方式進行數據獲取,更沒有必要在數據拷貝階段進行無謂的等待,而是能夠在I/O完成之后,通過信號或者回調函數的方式傳遞給應用程序,在此期間應用程序可以執行其他業務邏輯。

        帶你了解Nodejs中的非阻塞異步IO

        實際的異步I/O

        實際上,linux平臺下原生支持了異步I/O(AIO),但是目前 AIO 并不完善,因此在 Linux 下實現高并發網絡編程時都是以 I/O 復用模型為主。

        而Windows 下通過 IOCP 實現了真正的異步 I/O。

        多線程模擬異步I/O

        linux平臺下,Node利用線程池,通過讓部分線程進行阻塞I/O或者非阻塞I/O+輪詢的方式完成數據獲取,讓某一個單獨的線程進行計算,通過線程之間的通信,將I/O結果進行傳遞,這樣便實現了異步I/O的模擬。

        其實Windows平臺下的IOCP異步異步方案底層也是采用線程池的方式實現的,所不同的是,后者的線程池是由系統內核進行托管的。

        我們常說Node是單線程的,但其實只能說是JS執行在單線程中,無論是*nix還是windows平臺,底層都是利用線程池來完成I/O操作。

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产精品久久午夜夜伦鲁鲁| 9久热这里只有精品| 777久久精品一区二区三区无码| 亚洲国产精品激情在线观看| mm1313亚洲国产精品无码试看| 国产精品99久久免费观看| 亚洲精品国产品国语在线| 国产91在线精品| 国产精品合集一区二区三区| 色一乱一伦一图一区二区精品 | 欧美精品videosse精子| 久久亚洲中文字幕精品一区四| 国产成人精品亚洲精品| 精品国产日产一区二区三区| 国产精品天干天干综合网| 亚洲AV日韩精品久久久久久| 亚洲精品无码永久在线观看| 久久久久久国产精品免费免费| 国产精品V亚洲精品V日韩精品| 亚洲国产精品久久久久| 国产精品久久久久天天影视| 99久久国产综合精品麻豆| 91精品国产91久久久久福利| 国产国拍亚洲精品mv在线观看 | 国产三级精品三级| 国产精品无码一区二区在线观一| 91久久精品国产成人久久| 精品亚洲欧美高清不卡高清| 国产精品一级香蕉一区| 国产精品久久永久免费| 第一福利永久视频精品| 国产精品一二三区| 亚洲精品性视频| 亚洲综合一区二区精品导航| 2021国产三级精品三级在专区| 欧美精品免费线视频观看视频| 日本精品一区二区三区在线观看| 久久精品国产91久久综合麻豆自制 | 日韩精品一区二区三区视频| 日韩午夜高清福利片在线观看欧美亚洲精品suv | 日韩国产成人精品视频|