linux 网络io命令详解,Linux下五种网络IO模型详解
本文我們主要來了解一下Unix/Linux下5種網絡IO模型:blocking IO, nonblocking IO, IO multiplexing, signal driven IO, asynchronous IO的基本原理,更好的理解在高級語言中的異步編程,一起來看看吧,希望對大家學習linux有所幫助。
寫在前面
為了更好的理解下面提到的Linux下5種網絡IO的概念,我們還是有必要先理清幾個概念。
1.程序空間與內核空間
在Linux中,對于一次讀取IO的操作,數據并不會直接拷貝到程序的程序緩沖區。它首先會被拷貝到操作系統內核的緩沖區中,然后才會從操作系統內核的緩沖區拷貝到應用程序的緩沖區。p.s:?最后一句話非常重要,重復一遍。
1. Waiting for the data to be ready(等待數據到達內核緩沖區)
2.Copying the data from the kernel to the process(從內核緩沖區拷貝數據到程序緩沖區)
2.阻塞與非阻塞
阻塞就是說我們某一個請求不能立即得到返回應答,否則就可以理解為非阻塞。
3.同步IO與異步IO
這里先直接引用Stevens(POSIX)在Unix網絡編程中的定義:
A synchronous I/O operation causes the requesting process?to?be blocked?until?that I/O operation completes. An asynchronous I/O operation does?not?cause the requesting process?to?be blocked.
對于同步與異步,我們可以用一個簡單的生活場景來描述。當我們排隊在實體店買東西可以視作同步,而網購則可以視作異步。實體店排隊這種同步情形顯然是非常的浪費時間,等待的這段時間我們被阻塞住了不能干其他的事情,而網購只要我們提交一下訂單之后其他什么都不用管了,商品到了,快遞員給我們發送一個信號(打電話)我們直接到門口去拿,等待的這段時間我們可以用來擼代碼。
p.s:?等你閱讀完文章的后面部分,回過頭來看異步其實就是將等待的這段時間去處理IO操作,把CPU(我們的大腦)讓出來做其他更有價值的事情(擼代碼),而不是像同步那樣去傻傻地排隊。更加詳細準確的定義可以在閱讀完本文后面部分后參考維基百科。
4.文件描述符
在Linux下面一切皆文件, 文件描述符(file descriptor)是內核為文件所創建的索引 ,所有I/O操作都通過調用文件描述符(索引)來執行,包括下面我們要提到的socket。Linux剛啟動的時候會自動設置0是標準輸入,1是標準輸出,2是標準錯誤。
5種網絡IO模型
1.blocking IO(阻塞IO)
如圖所示,進程調用一個recvfrom請求,但是它不能立刻收到回復,直到數據返回,然后將數據從內核空間復制到程序空間。這里我們再次回顧開篇提到的兩個過程:
1.Waiting for the data to be ready(等待數據到達內核緩沖區)
2.Copying the data from the kernel to the process(從內核緩沖區拷貝數據到程序緩沖區)
注意到沒有,在上面這兩個過程中,進程都處于blocked(阻塞)狀態,在等待數據返回的過程中不能空閑出來干其他的事情。
2.nonblocking IO(非阻塞IO)
當我們設置一個socket為nonblocking(非阻塞),相當于告訴內核當我們請求的IO操作不能立即得到返回結果,不要把進程設置為sleep狀態,而是返回一個錯誤信息(下圖中的EWOULDBLOCK)。
我們來分析一下圖片中的整個流程。前三次我們調用recvfrom請求,但是并沒有數據返回,所以內核只能返回一個錯誤信息(EWOULDBLOCK)。但是當我們第四次調用recvfrom,數據已經準備好了,然后將它從內核空間復制到程序空間。
在非阻塞狀態下,我們的過程一(wait for data)并不是完全的阻塞的,但是過程二(copy data from kernel to user)依然處于一個阻塞狀態。
3.IO multiplexing(IO復用)
IO復用的好處是我們可以通過(select/poll/epoll)一個時刻處理多個文件描述符,這里以select為例來分析一下。
IO復用實際上也是完全阻塞的,請仔細看圖(圖中我們有兩個return,前面我們都只有一個return),Stevens在書中提到這里并沒有阻塞在recfrom階段而是阻塞在select階段,其實這樣說并不是非常的嚴謹,因為recform其實也是一個阻塞過程(圖中也描述了),recvfrom過程中進程除了等待copy data from kernel to user以外,并不能空閑出來干其他事情。
兩個過程的都是阻塞的,看起來IO復用和阻塞IO相比似乎并沒有什么優勢,而且還需要兩個return,但是這里注意在IO復用中我們可以同時監聽多個文件描述符。
4.signal driven IO(信號驅動IO)
我們也可以使用信號驅動IO,要求內核通知我們當文件描述符準備就緒以后發送相應的信號。
我們根據圖片來分析一下。?階段1:?我們首先設置socket為一個信號驅動IO,并且通過sigaction system call安裝一個signal handler,注意這個過程是瞬時的,所以這個階段是非阻塞的。?階段2?:?當數據已經準備好了以后,一個SIGIO信號傳送給我們的進程告訴我們數據準備好了,然后進程開始等待數據從內核空間復制到程序空間(copy data from kernel to user),這個過程是阻塞的,因為我們的進程只能等待數據復制完畢。
5.asynchronous IO(異步IO)
我們來看一下異步的概念,異步就是說對于上面兩個步驟(wait for data?和copy of the data from the kernel to our buffer)當它們完成的時候會自動通知進程,在這段時間里面進程什么都不用操心,就像網購一樣,下了單什么也不用管了等著快遞員通知我們(即我們通常所說的callback)。?相比前面的信號驅動IO,異步IO兩個階段都是非阻塞的。
6.小結
阻塞式IO(默認),非阻塞式IO(nonblock),IO復用(select/poll/epoll),signal driven IO(信號驅動IO)都是屬于同步型IO,因為在第二個階段:?從內核空間拷貝數據到程序空間的時候不能干別的事。只有異步I/O模型(AIO)才是符合我們上面對于異步型IO操作的含義,在1.wait for data,2.copy data from kernel to user,這兩個等待/接收數據的時間段內進程可以干其他的事情,只要等著被通知就可以了。
打開App,閱讀手記
總結
以上是生活随笔為你收集整理的linux 网络io命令详解,Linux下五种网络IO模型详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下usb驱动配置文件,Linu
- 下一篇: linux8安装bbr_CentOS 7