(轉)Linux網絡編程(5):I/O模型

    這一部分的內容本來應該作爲第四部分內容,置於上一講之中的。由於當時自己學習時也存在很大的困惑,邊學邊用,因此造成了知識體系的不連貫性。我們開始學習吧。

(1)什麼是I/O複用(I/O multiplexing)呢?

        當你編寫的程序需要同時處理多個描述符(socket、file、device),你又不知道什麼時候(比方說有數據可以讀了)應該去操作(讀/寫)哪個描述符。這時候我們就要用到I/O複用。其實,I/O複用是一種讓進程預先“警告”內核能力,使得內核一旦發現進程預先告知時指定的一個或多個I/O條件(就是描述符)就緒(可以讀/寫了),內核就通知進程。
(2)I/O複用運用場合
1、如果一個TCP服務器既要處理監聽套接字,又要處理已連接套接字,一般就要使用I/O複用;
2、當客戶端處理多個描述符(通常是交互式輸入和網絡套接字)時,就必須使用I/O複用;
3、如果一個服務器既要處理TCP,又要處理UDP,一般就要使用I/O複用;
4、如果一個服務器要處理多個服務或多個協議,一般就要使用I/O複用。
(3)I/O模型
1、阻塞式I/O

        UDP函數recvfrom的內核到應用層、應用層到內核的調用過程是這樣的:首先把描述符、接受數據緩衝地址、大小傳遞給內核,但是如果此時與該套接口相應的緩衝區沒有數據,這個時候就recvfrom就會卡(阻塞)在這裏,知道數據到來的時候,再把數據拷貝到應用層,也就是傳進來的地址空間,如果沒有數據到來,就會使該函數阻塞在那裏,這就叫做阻塞I/O模型,如下圖:


2、非阻塞式I/O

        如果recvfrom從應用層到內核的時候,如果該緩衝區沒有數據的話,就直接給我返回,並且返回一個EWOULDBLOCK錯誤,一般都對非阻塞I/O模型進行輪詢,就是一直在檢查這個狀態,看內核是不是有數據到來調用,過程如下圖:


3、I/O複用(select和poll)

        設置一組套接字,如果這些套接字有一個以上出現了可讀、可寫、或者異常,select都會返回,這個時候,可以檢查室哪個套接字狀態達到了,因爲select函數的套接字集是 值=結果 的,當select返回的時候,集合中的套接字是變化的,這個返回的套接字是滿足要求的,通常程序的做法是,對想要了解的套接字,進行分開處理。使用select的好處是:能夠等待多個套接字準備好。 使用select需要兩個而不是單個系統調用,其優勢在於我們可以等待多個描述符就緒。另外,與I/O複用密切相關的另一種I/O模型是在多線程中使用阻塞式I/O,它沒有使用select阻塞在多個文件描述符上,而是使用多個線程(每個文件描述符一個線程),這樣每個線程都可以自由地調用諸如recvfrom之類的阻塞式I/O系統調用了。


4、信號驅動式I/O

       當內核爲我們準備好數據的時候,就會發送 SIGIO 信號,我們可以調用 sigaction 安裝 SIGIO 信號的處理函數,這個時候就可以在 SIGIO 信號處理函數中進行 recvfrom 函數來接受數據報。


5、異步I/O

      讓內核拷貝完之後通知我們。信號驅動I/O是當內核準備好數據的時候,通知我們可以調用recvfrom了,而異步I/O模型是內核通知我們I/O操作完成的時候通知我們。



參考資源:http://www.linuxidc.com/Linux/2012-08/66976.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章