1. 程式人生 > >簡明網路I/O模型---同步非同步阻塞非阻塞之惑

簡明網路I/O模型---同步非同步阻塞非阻塞之惑

網路I/O模型

人多了,就會有問題。web剛出現的時候,光顧的人很少。近年來網路應用規模逐漸擴大,應用的架構也需要隨之改變。C10k的問題,讓工程師們需要思考服務的效能與應用的併發能力。

網路應用需要處理的無非就是兩大類問題,網路I/O資料計算。相對於後者,網路I/O的延遲,給應用帶來的效能瓶頸大於後者。網路I/O的模型大致有如下幾種:

  • 同步模型(synchronous I/O)
    • 阻塞I/O(bloking I/O)
    • 非阻塞I/O(non-blocking I/O)
    • 多路複用I/O(multiplexing I/O)
    • 訊號驅動式I/O(signal-driven I/O)
  • 非同步I/O(asynchronous I/O)

網路I/O的本質是socket的讀取,socket在linux系統被抽象為流,I/O可以理解為對流的操作。這個操作又分為兩個階段:

  1. 等待流資料準備(wating for the data to be ready)。
  2. 從核心向程序複製資料(copying the data from the kernel to the process)。

對於socket流而已,

  • 第一步通常涉及等待網路上的資料分組到達,然後被複制到核心的某個緩衝區。
  • 第二步把資料從核心緩衝區複製到應用程序緩衝區。

I/O模型

舉個簡單比喻,來了解這幾種模型。網路IO好比釣魚,等待魚上鉤就是網路中等待資料準備好的過程,魚上鉤了,把魚拉上岸就是核心複製資料階段。釣魚的人就是一個應用程序。

阻塞I/O(bloking I/O)

阻塞I/O是最流行的I/O模型。它符合人們最常見的思考邏輯。阻塞就是程序 "被" 休息, CPU處理其它程序去了

。在網路I/O的時候,程序發起recvform系統呼叫,然後程序就被阻塞了,什麼也不幹,直到資料準備好,並且將資料從核心複製到使用者程序,最後程序再處理資料,在等待資料到處理資料的兩個階段,整個程序都被阻塞。不能處理別的網路I/O。大致如下圖:


1.png

這就好比我們去釣魚,拋竿之後就一直在岸邊等,直到等待魚上鉤。然後再一次拋竿,等待下一條魚上鉤,等待的時候,什麼事情也不做,大概會胡思亂想吧。

阻塞IO的特點就是在IO執行的兩個階段都被block了

非阻塞I/O(non-bloking I/O)

在網路I/O時候,非阻塞I/O也會進行recvform系統呼叫,檢查資料是否準備好,與阻塞I/O不一樣,"非阻塞將大的整片時間的阻塞分成N多的小的阻塞, 所以程序不斷地有機會 '被' CPU光顧"。

也就是說非阻塞的recvform系統呼叫呼叫之後,程序並沒有被阻塞,核心馬上返回給程序,如果資料還沒準備好,此時會返回一個error。程序在返回之後,可以乾點別的事情,然後再發起recvform系統呼叫。重複上面的過程,迴圈往復的進行recvform系統呼叫。這個過程通常被稱之為輪詢。輪詢檢查核心資料,直到資料準備好,再拷貝資料到程序,進行資料處理。需要注意,拷貝資料整個過程,程序仍然是屬於阻塞的狀態。


2.png

我們再用釣魚的方式來類別,當我們拋竿入水之後,就看下魚漂是否有動靜,如果沒有魚上鉤,就去幹點別的事情,比如再挖幾條蚯蚓。然後不久又來看看魚漂是否有魚上鉤。這樣往返的檢查又離開,直到魚上鉤,再進行處理。

非阻塞 IO的特點是使用者程序需要不斷的主動詢問kernel資料是否準備好。

多路複用I/O(multiplexing I/O)

可以看出,由於非阻塞的呼叫,輪詢佔據了很大一部分過程,輪詢會消耗大量的CPU時間。結合前面兩種模式。如果輪詢不是程序的使用者態,而是有人幫忙就好了。多路複用正好處理這樣的問題。

多路複用有兩個特別的系統呼叫selectpoll。select呼叫是核心級別的,select輪詢相對非阻塞的輪詢的區別在於---前者可以等待多個socket,當其中任何一個socket的資料準好了,就能返回進行可讀,然後程序再進行recvform系統呼叫,將資料由核心拷貝到使用者程序,當然這個過程是阻塞的。多路複用有兩種阻塞,select或poll呼叫之後,會阻塞程序,與第一種阻塞不同在於,此時的select不是等到socket資料全部到達再處理, 而是有了一部分資料就會呼叫使用者程序來處理。如何知道有一部分資料到達了呢?監視的事情交給了核心,核心負責資料到達的處理。也可以理解為"非阻塞"吧。


3.png

對於多路複用,也就是輪詢多個socket。釣魚的時候,我們僱了一個幫手,他可以同時拋下多個釣魚竿,任何一杆的魚一上鉤,他就會拉桿。他只負責幫我們釣魚,並不會幫我們處理,所以我們還得在一幫等著,等他把收杆。我們再處理魚。多路複用既然可以處理多個I/O,也就帶來了新的問題,多個I/O之間的順序變得不確定了,當然也可以針對不同的編號。

多路複用的特點是通過一種機制一個程序能同時等待IO檔案描述符,核心監視這些檔案描述符(套接字描述符),其中的任意一個進入讀就緒狀態,select, poll,epoll函式就可以返回。對於監視的方式,又可以分為 select, poll, epoll三種方式。

瞭解了前面三種模式,在使用者程序進行系統呼叫的時候,他們在等待資料到來的時候,處理的方式不一樣,直接等待,輪詢,select或poll輪詢,第一個過程有的阻塞,有的不阻塞,有的可以阻塞又可以不阻塞。當時第二個過程都是阻塞的。從整個I/O過程來看,他們都是順序執行的,因此可以歸為同步模型(asynchronous)。都是程序主動向核心檢查。

非同步I/O(asynchronous I/O)

相對於同步I/O,非同步I/O不是順序執行。使用者程序進行aio_read系統呼叫之後,無論核心資料是否準備好,都會直接返回給使用者程序,然後使用者態程序可以去做別的事情。等到socket資料準備好了,核心直接複製資料給程序,然後從核心向程序傳送通知。I/O兩個階段,程序都是非阻塞的。


4.png

比之前的釣魚方式不一樣,這一次我們僱了一個釣魚高手。他不僅會釣魚,還會在魚上鉤之後給我們發簡訊,通知我們魚已經準備好了。我們只要委託他去拋竿,然後就能跑去幹別的事情了,直到他的簡訊。我們再回來處理已經上岸的魚。

同步和非同步的區別

通過對上述幾種模型的討論,需要區分阻塞和非阻塞,同步和非同步。他們其實是兩組概念。區別前一組比較容易,後一種往往容易和前面混合。在我看來,所謂同步就是在整個I/O過程。尤其是拷貝資料的過程是阻塞程序的,並且都是應用程序態去檢查核心態。而非同步則是整個過程I/O過程使用者程序都是非阻塞的,並且當拷貝資料的時是由核心傳送通知給使用者程序。


5.png

對於同步模型,主要是第一階段處理方法不一樣。而非同步模型,兩個階段都不一樣。這裡我們忽略了訊號驅動模式。這幾個名詞還是容易讓人迷惑,只有同步模型才考慮阻塞和非阻塞,因為非同步肯定是非阻塞,非同步非阻塞的說法感覺畫蛇添足。

本文所討論的IO模型來自大名鼎鼎的《unix網路程式設計:卷1套接字聯網API》。單臺伺服器中的linux系統。分散式的環境或許會不一樣。個人學習筆記,參考了網路上大多數文章,做了一點小測試。



文/人世間(簡書作者)
原文連結:http://www.jianshu.com/p/55eb83d60ab1
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。

相關推薦

簡明網路I/O模型---同步非同步阻塞阻塞

網路I/O模型 人多了,就會有問題。web剛出現的時候,光顧的人很少。近年來網路應用規模逐漸擴大,應用的架構也需要隨之改變。C10k的問題,讓工程師們需要思考服務的效能與應用的併發能力。 網路應用需要處理的無非就是兩大類問題,網路I/O,資料計算。相對於後者,網路I/O的延

[轉]簡明網路I/O模型---同步非同步阻塞阻塞

網路I/O模型 人多了,就會有問題。web剛出現的時候,光顧的人很少。近年來網路應用規模逐漸擴大,應用的架構也需要隨之改變。C10k的問題,讓工程師們需要思考服務的效能與應用的併發能力。 網路應用需要處理的無非就是兩大類問題,網路I/O,資料計算。相對於後者,網路I/O的延遲,給應用帶來的效能瓶頸大於

網路I/O模型---同步非同步阻塞阻塞

網路I/O模型---同步非同步阻塞非阻塞之惑 網路I/O模型 人多了,就會有問題。web剛出現的時候,光顧的人很少。近年來網路應用規模逐漸擴大,應用的架構也需要隨之改變。C10k的問題,讓工程師們需要思考服務的效能與應用的併發能力。 網路應用需要處理的無非就是兩大類問題,網

網絡I/O模型---同步異步阻塞阻塞

本質 結果 順序執行 其中 ges package 混合 signal 同時 網絡I/O模型 人多了,就會有問題。web剛出現的時候,光顧的人很少。近年來網絡應用規模逐漸擴大,應用的架構也需要隨之改變。C10k的問題,讓工程師們需要思考服務的性能與應用的並發能力。 網絡應

I/O模型非同步事件)

非同步事件    WSAEventSelect模型是WindowsSockets提供的另外一個有用的非同步I/O模型。該模型允許一個或多個套接字上接收以事件為基礎的網路事件通知。Windows Sockets應用程式在建立套接字後,呼叫WSAEventSlect()函式,將一

I/O模型非同步選擇)

非同步選擇 非同步選擇(WSAAsyncSelect)模型是一個有用的非同步 I/O 模型。利用這個模型,應用程式可在一個套接字上,接收以 Windows 訊息為基礎的網路事件通知。具體的做法是在建好一個套接字後,呼叫WSAAsyncSelect函式。 WSAAsyncSelect模型是Se

在 C/C++ 非同步 I/O 中使用 MariaDB 的阻塞介面

對 C/C++,MySQL 提供的庫傳統上都是阻塞操作,因此適合多執行緒 / 程序伺服器架構程式設計。但是如果用 C/C++ 編寫伺服器,往往對效能會有極致要求,此時採用非阻塞的非同步 I/O 才是更好的框架。 所幸,從 MySQL fork 出來的 MariaDB

網路I/O模型--5種常見的網路I/O模型

  阻塞與非阻塞   阻塞就是卡在那兒什麼也不做,雙方之間也沒有資訊溝通。   非阻塞就是即使對方不能馬上完成請求,雙方之間也有資訊的溝通。 同步與非同步   同步就是一件事件只由一個過程處理完成,不論阻塞與非阻塞,最後完成這個事情的都是同一個過程   非同步就是一件事由兩個過程完成,前

Linux 網路 I/O 模型簡介(圖文)

1、介紹     Linux 的核心將所有外部裝置都看做一個檔案來操作(一切皆檔案),對一個檔案的讀寫操作會呼叫核心提供的系統命令,返回一個file descriptor(fd,檔案描述符)。而對一個socket的讀寫也會有響應的描述符,稱為socket fd(soc

Windows作業系統網路I/O模型

window 下的套接字以來兩種方式執行I/O操作,阻塞IO 非阻塞IO,一般預設使用的是阻塞IO 即執行緒會等待不會把控制權利立刻返回給程式,這就意為一個執行緒在某一個時候只能夠去執行一個IO操作。 如果服務端想和多個客戶端同時進行通訊的話就要使用多執行緒程式設計,但

沒搞清楚網路I/O模型?那怎麼入門Netty

微信搜尋【阿丸筆記】,關注Java/MySQL/中介軟體各系列原創實戰筆記,乾貨滿滿。   本文是Netty系列筆記第二篇 Netty是網路應用框架,所以從最本質的角度來看,是對網路I/O模型的封裝使用。 因此,要深刻理解Netty的高效能,也必須從網路I/O模型說起。   看完

網路I/O模型到Netty,先深入瞭解下I/O多路複用

微信搜尋【阿丸筆記】,關注Java/MySQL/中介軟體各系列原創實戰筆記,乾貨滿滿。   本文是Netty系列第3篇 上一篇文章我們瞭解了Unix標準的5種網路I/O模型,知道了它們的核心區別與各自的優缺點。尤其是I/O多路複用模型,在高併發場景下,有著非常好的優勢。而Netty也採用了I

網路程式設計中阻塞阻塞同步非同步I/O模型的理解

1. 概念理解      在進行網路程式設計時,我們常常見到同步(Sync)/非同步(Async),阻塞(Block)/非阻塞(Unblock)四種呼叫方式:同步:所謂同步,就是在發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回。也就是必須一件一件事做,等前一件做完了才能做下一件事。 例如

socket阻塞阻塞 同步非同步 I/O模型

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

socket阻塞阻塞同步非同步I/O模型(轉載只為查閱方便,若有侵權,立刪)

socket阻塞與非阻塞,同步與非同步 作者:huangguisu     1. 概念理解        在進行網路程式設計時,我們常常見到同步(Sync)/非同步(Async),阻塞(Block)/非阻塞(Unbl

Windows I/O模型同步/非同步阻塞/阻塞

同步  所謂同步,就是在發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回。按照這個定義,其實絕大多數函式都是同步呼叫(例如sin, isdigit等)。但是一般而言,我們在說同步、非同步的時候,特指那些需要其他部件協作或者需要一定時間完成的任務。最常見的例子就是 SendMessag

聊聊阻塞阻塞同步非同步I/O模型

1. 概念理解 在進行網路程式設計時,我們常常見到同步(Sync)/非同步(Async),阻塞(Block)/非阻塞(Unblock)四種呼叫方式: 同步/非同步主要針對C端:  同步: 所謂同步,就是在c端發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回。也就是必須一件一件事做,等前一件做完了才能做

I/O模型同步I/O非同步I/O阻塞I/O阻塞I/O

同步(synchronous) IO和非同步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分別是什麼,到底有什麼區別? 這個問題其實不同的人給出的答案都可能不同,在大部分的博文中(包括WIKI在內),我們很可能

socket阻塞阻塞同步非同步I/O模型

1. 概念理解      在進行網路程式設計時,我們常常見到同步(Sync)/非同步(Async),阻塞(Block)/非阻塞(Unblock)四種呼叫方式: 同步/非同步主要針對C端: 同步:所謂同步,就是在c端發出一個功能呼叫時,在沒有得到結果之前,該

I/O 模型阻塞阻塞同步非同步

一個IO操作,需要2步。 以read為例,  read --> sys_Read --> 驅動中的buffer資料 OR 網路中的udp/tcp報文 等等 同步/非同步 是否阻塞在第二步。 也就是 sys_Read -->