微信搜索:碼農StayUp
主頁地址: https://gozhuyinglong.github.io
源碼分享: https://github.com/gozhuyinglong/blog-demos
在平常 Coding 中,多多少少都會接觸到網絡 IO,就會想要深刻了解一下。看了不少文章,老是雲裏霧裏的感受,直到讀了《UNIX網絡編程 卷1:套接字聯網API》中的介紹後,才豁然開朗。這裏就給你們分享一下,若有不對,歡迎指出。git
爲了便於理解後面的內容,咱們先來了解一些概念。github
Socket 中文翻譯爲套接字,是計算機網絡中進程間進行雙向通訊的端點的抽象。一個 Socket 表明了網絡通訊的一端,是由操做系統提供的進程間通訊機制。編程
每一個 Socket 被建立後,都會在內核中分配兩個緩衝區:輸入緩衝區和輸出緩衝區。服務器
操做系統的進程空間能夠分爲用戶空間(User Space)和內核空間(Kernel Space),它們須要不一樣的執行權限。微信
recv()
函數,會將輸入緩衝區中的內容拷貝到用戶緩衝區。
下面列舉了一些 Linux 操做系統中的系統調用接口(部分函數後面章節會用到):網絡
阻塞與非阻塞,用於描述調用者在等待返回結果時的狀態。異步
而同步與異步,用於描述調用結果的返回機制(或者叫通訊機制)。socket
IO 模型是指:用什麼樣的通道或者說是通訊模式進行數據的傳輸,這很大程序上決定了程序通訊的性能。函數
Linux 系統爲咱們提供五種可用的 IO 模型:阻塞式 IO 模型、非阻塞式 IO 模型、IO 多路複用模型、信號驅動 IO 模型和異步 IO 模型。性能
阻塞式 IO (Blocking IO):應用進程從發起 IO 系統調用,至內核返回成功標識,這整個期間是處於阻塞狀態的。
非阻塞式IO(Non-Blocking IO):應用進程能夠將 Socket 設置爲非阻塞,這樣應用進程在發起 IO 系統調用後,會馬上返回。應用進程能夠輪詢的發起 IO 系統調用,直到內核返回成功標識。
IO 多路複用(IO Multiplexin):能夠將多個應用進程的 Socket 註冊到一個 Select(多路複用器)上,而後使用一個進程來監聽該 Select(該操做會阻塞),Select 會監聽全部註冊進來的 Socket。只要有一個 Socket 的數據準備好,就會返回該Socket。再由應用進程發起 IO 系統調用,來完成數據讀取。
信號驅動 IO(Signal Driven IO):能夠爲 Socket 開啓信號驅動 IO 功能,應用進程需向內核註冊一個信號處理程序,該操做並當即返回。當內核中有數據準備好,會發送一個信號給應用進程,應用進程即可以在信號處理程序中發起 IO 系統調用,來完成數據讀取了。
異步 IO(Asynchronous IO): 應用進程發起 IO 系統調用後,會當即返回。當內核中數據徹底準備後,而且也複製到了用戶空間,會產生一個信號來通知應用進程。
從上述五種 IO 模型能夠看出,應用進程對內核發起 IO 系統調用後,內核會通過兩個階段來完成數據的傳輸:
前四種模型的第二階段是相同的,都是處於阻塞狀態,其主要區別在第一階段。而異步 IO 模型則不一樣,應用進程在這兩個階段是徹底不阻塞的。
IO 模型 | 第一階段 | 第二階段 |
---|---|---|
阻塞式IO | 阻塞 | 阻塞 |
非阻塞式IO | 非阻塞 | 阻塞 |
IO多路程複用 | 阻塞(Select) | 阻塞 |
信號驅動式IO | 異步 | 阻塞 |
異步IO | 異步 | 異步 |