中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解常見的IO模型:阻塞、非阻塞、多路復用、異步

發布時間:2021-10-13 15:21:21 來源:億速云 閱讀:227 作者:iii 欄目:編程語言

本篇內容主要講解“如何理解常見的IO模型:阻塞、非阻塞、多路復用、異步”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何理解常見的IO模型:阻塞、非阻塞、多路復用、異步”吧!

在Unix網絡編程中,史蒂文斯給出了5種IO編程模型,其中最重點、也最常用的是多路復用模型(Multiplexing)。 這5種模型分別為:

  • 阻塞式IO

  • 非阻塞式IO

  • IO多路復用(multiplexing io),基于select/poll/epoll

  • 信號驅動式IO SIGIO

  • 異步IO(posix aio_abi和libaio)

想要說明清楚這幾個模型,一個很好的方式是把網絡IO分為兩個階段來理解。第一階段,從客戶端向服務端發送請求開始,到數據從網絡傳輸到達,完全準備好為止。第二階段,數據從內核空間復制到程序緩存(即用戶空間),這個階段才是應用真正執行recvfrom系統調用的階段。在第一階段,程序要么阻塞在recvfrom調用上,要么阻塞在select之類的方法上,或者干其他的事情去了(輪詢、異步等)。

如何理解常見的IO模型:阻塞、非阻塞、多路復用、異步

有了這個基本認知,我們再來逐個審視這幾種模型。

阻塞式I/O模型

阻塞式IO(blocking I/O)是最基本的IO模型,也是日常使用中默認的模式。

如何理解常見的IO模型:阻塞、非阻塞、多路復用、異步

如上圖,應用發出請求,試圖執行recvfrom系統調用,以獲取數據,由于數據還沒準備好(也許服務端才開始處理請求),當前請求線程被阻塞,只能傻傻的等待,直到數據可讀或者拋出異常。如果是單線程應用,主線程掛起,CPU空置。如果是多線程,當前線程掛起,CPU切換時間片去執行其他線程。

非阻塞式IO模型

一般的Socket對象都會有一個setblocking(False)或者ConfigureBlocing(false)之類的方法,將當前IO線程設置成非阻塞模式。

如何理解常見的IO模型:阻塞、非阻塞、多路復用、異步

如圖,當socket設置為nonblocking時,在一階段(數據準備階段,還記得前面說的二階段IO么,這里派上了用場)線程會不斷的發起recvfrom輪詢,如果還沒有準備好數據,會得到一個EWouldBLOCK錯誤信號,直到數據準備好之后,開始真正執行recvfrom拉取數據。輪詢會極大的消耗CPU時間,所以這種模型極少用到。

IO多路復用

I/O復用,即I/O multiplexing,這是一種基于select函數的編程模型,也是最常用的一種。有些人喜歡把它稱作異步阻塞模型,我覺得這種叫法很容易讓人產生誤解,實際上這個模型和所謂的異步I/O沒有半毛錢關系。

如何理解常見的IO模型:阻塞、非阻塞、多路復用、異步

如上圖,在第一階段,我們可以通過select函數注冊多路IO對象。每一個注冊的IO對象都會阻塞在select函數上,直到IO對象的狀態發生改變。此時數據已經準備好讀/寫。調度器遍歷這些IO對象,返回準備好讀/寫的IO對象。緊接著進入第二階段,開始對準備好的IO對象調用recvfrom函數。

對于多路復用模型,Java NIO基于select庫實現了調度器Selector,python的selectors模塊分別提供了基于selectpoll以及epoll庫的封裝對象。

通過以上過程,我們還可以看到,其實IO多路復用阻塞IO很相似,基本兩個階段都在阻塞狀態。只不過前者第一階段阻塞在select函數上,第二階段阻塞在recvfrom調用上;而后者全程阻塞在recvfrom上。而且IO多路復用由于需要注冊、遍歷IO對象,其實涉及到更多的步驟開銷。但是多路復用的優勢正在于可以同時對接多個IO對象,結合多線程技術,可以帶來很大的靈活性。

異步IO模型

前面提到的三種模型,本質上在真正的IO階段(第二階段),都會阻塞。而在異步IO模型中,應用發出數據請求后,不再等待,直接返回。期間線程也不會阻塞。之后由內核處理兩個階段IO,然后給應用發送信號,程序直接獲取數據。

如何理解常見的IO模型:阻塞、非阻塞、多路復用、異步

基于Unix系統有一個POSIX異步IO庫——aio_abi,以及一個第三方庫aiolib,后者可能更加知名。異步IO模型非常復雜,一般很少見到。另外我也有一些疑惑,python中的asyncio包提出的協程概念,和這里的異步IO是否為同一件事物。史蒂文斯在這里描述的異步明顯需要基于系統內核的相關實現,和asyncio這種單純的編程概念,大概說的不是一個層級的東西吧。

隱喻

最后還是說一個比喻吧。如果把IO模型比作網購,在你提交訂單的一刻到快遞員將貨物帶到你家小區門口期間,可看作一階段IO。之后小哥給你打電話:“你的快遞,快開門”,這相當于數據準備好了,并發送了通知。之后,你跑到門口將快遞一件一件搬到家里,這是第二階段。

阻塞模型相當于你提了訂單,就不吃不喝,只等著快遞,直到小哥給你打電話,然后吭哧吭哧把快遞搬到家,你才開始吃喝、睡覺等。非阻塞模型下,你提交訂單后就開始自由行動了。但是仍然會每隔幾分鐘跑到小區門口看看快遞到了沒(輪詢),一直把自己搞得精疲力盡。直到小哥給你打電話,你把快遞搬回家才算消停。多路復用模型下,你同時提交了多個訂單,但不再傻傻的朝門口來回跑了,而是緊緊盯著菜鳥裹裹信息(阻塞在select),直到其上顯示至少有一個快遞到了,你會嗖的跑過去,當然,快遞仍然自己搬(recvfrom阻塞)。異步模型下,你雇了一個萬能管家吉福斯,你只要下完訂單,就不用操心了,他會打點好一切,最后他會把快遞按照你們約定的地點、方式,直接送到你的手上。

到此,相信大家對“如何理解常見的IO模型:阻塞、非阻塞、多路復用、異步”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

理塘县| 偏关县| 南昌市| 石泉县| 泸水县| 手机| 乌恰县| 炉霍县| 南丹县| 昌乐县| 宜丰县| 探索| 桦川县| 南宁市| 界首市| 佛山市| 西乡县| 南涧| 高平市| 乌拉特前旗| 澄江县| 怀来县| 五大连池市| 桂平市| 蕲春县| 郴州市| 天门市| 颍上县| 武清区| 乌什县| 米易县| 溧阳市| 扎囊县| 莱州市| 天祝| 新余市| 东光县| 永善县| 上犹县| 甘德县| 古交市|