• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 200, comments - 8, trackbacks - 0, articles - 0

            五種I/O 模式:
            【1】        阻塞 I/O           (Linux下的I/O操作默認是阻塞I/O,即open和socket創建的I/O都是阻塞I/O)
            【2】        非阻塞 I/O        (可以通過fcntl或者open時使用O_NONBLOCK參數,將fd設置為非阻塞的I/O)
            【3】        I/O 多路復用     (I/O多路復用,通常需要非阻塞I/O配合使用)
            【4】        信號驅動 I/O    (SIGIO)
            【5】        異步 I/O

             

            一般來說,程序進行輸入操作有兩步:
            1.等待有數據可以讀
            2.將數據從系統內核中拷貝到程序的數據區。

            對于sock編程來說:

                     第一步:   一般來說是等待數據從網絡上傳到本地。當數據包到達的時候,數據將會從網絡層拷貝到內核的緩存中;

                     第二步:   是從內核中把數據拷貝到程序的數據區中。

             

            阻塞I/O模式                            //進程處于阻塞模式時,讓出CPU,進入休眠狀態
                    阻塞 I/O 模式是最普遍使用的 I/O 模式。是Linux系統下缺省的IO模式。

                   大部分程序使用的都是阻塞模式的 I/O 。

                   一個套接字建立后所處于的模式就是阻塞 I/O 模式。(因為Linux系統默認的IO模式是阻塞模式)


            對于一個 UDP 套接字來說,數據就緒的標志比較簡單:
            (1)已經收到了一整個數據報
            (2)沒有收到。
            而 TCP 這個概念就比較復雜,需要附加一些其他的變量。

                   一個進程調用 recvfrom  ,然后系統調用并不返回知道有數據報到達本地系統,然后系統將數據拷貝到進程的緩存中。 (如果系統調用收到一個中斷信號,則它的調用會被中斷)

               我們稱這個進程在調用recvfrom一直到從recvfrom返回這段時間是阻塞的。當recvfrom正常返回時,我們的進程繼續它的操作。

             
             ---------------------------------------------------------------------------------

            非阻塞模式I/O                           //非阻塞模式的使用并不普遍,因為非阻塞模式會浪費大量的CPU資源。
                   當我們將一個套接字設置為非阻塞模式,我們相當于告訴了系統內核: “當我請求的I/O 操作不能夠馬上完成,你想讓我的進程進行休眠等待的時候,不要這么做,請馬上返回一個錯誤給我。”
                  我們開始對 recvfrom 的三次調用,因為系統還沒有接收到網絡數據,所以內核馬上返回一個 EWOULDBLOCK的錯誤。

                  第四次我們調用 recvfrom 函數,一個數據報已經到達了,內核將它拷貝到我們的應用程序的緩沖區中,然后 recvfrom 正常返回,我們就可以對接收到的數據進行處理了。
                  當一個應用程序使用了非阻塞模式的套接字,它需要使用一個循環來不聽的測試是否一個文件描述符有數據可讀(稱做 polling(輪詢))。應用程序不停的 polling 內核來檢查是否 I/O操作已經就緒。這將是一個極浪費 CPU資源的操作。這種模式使用中不是很普遍。

             
            例如:
                     對管道的操作,最好使用非阻塞方式!
             
             
              ---------------------------------------------------------------------------------
             

            I/O多路復用                             //針對批量IP操作時,使用I/O多路復用,非常有好。

                   在使用 I/O 多路技術的時候,我們調用 select()函數和 poll()函數或epoll函數(2.6內核開始支持),在調用它們的時候阻塞,而不是我們來調用 recvfrom(或recv)的時候阻塞。
                   當我們調用 select函數阻塞的時候,select 函數等待數據報套接字進入讀就緒狀態。當select函數返回的時候, 也就是套接字可以讀取數據的時候。 這時候我們就可以調用 recvfrom函數來將數據拷貝到我們的程序緩沖區中。
                    對于單個I/O操作,和阻塞模式相比較,select()和poll()或epoll并沒有什么高級的地方。
                    而且,在阻塞模式下只需要調用一個函數:
                                         讀取或發送函數。
                               在使用了多路復用技術后,我們需要調用兩個函數了:
                                         先調用 select()函數或poll()函數,然后才能進行真正的讀寫。

                   多路復用的高級之處在于::

                          它能同時等待多個文件描述符,而這些文件描述符(套接字描述符)其中的任意一個進入讀就緒狀態,select()函數就可以返回。

             
            IO 多路技術一般在下面這些情況中被使用:
            1、當一個客戶端需要同時處理多個文件描述符的輸入輸出操作的時候(一般來說是標準的輸入輸出和網絡套接字),I/O 多路復用技術將會有機會得到使用。
            2、當程序需要同時進行多個套接字的操作的時候。
            3、如果一個 TCP 服務器程序同時處理正在偵聽網絡連接的套接字和已經連接好的套接字。
            4、如果一個服務器程序同時使用 TCP 和 UDP 協議。
            5、如果一個服務器同時使用多種服務并且每種服務可能使用不同的協議(比如 inetd就是這樣的)。
             
             
             
            異步IO模式有::
                   1、信號驅動I/O模式
                   2、異步I/O模式
            信號驅動I/O模式                                                   //自己沒有用過。

                   我們可以使用信號,讓內核在文件描述符就緒的時候使用 SIGIO 信號來通知我們。我們將這種模式稱為信號驅動 I/O 模式。


            為了在一個套接字上使用信號驅動 I/O 操作,下面這三步是所必須的。

            (1)一個和 SIGIO信號的處理函數必須設定。
            (2)套接字的擁有者必須被設定。一般來說是使用 fcntl 函數的 F_SETOWN 參數來
            進行設定擁有者。
            (3)套接字必須被允許使用異步 I/O。一般是通過調用 fcntl 函數的 F_SETFL 命令,O_ASYNC為參數來實現。

                   雖然設定套接字為異步 I/O 非常簡單,但是使用起來困難的部分是怎樣在程序中斷定產生 SIGIO信號發送給套接字屬主的時候,程序處在什么狀態。

            1.UDP 套接字的 SIGIO 信號                    (比較簡單)
            在 UDP 協議上使用異步 I/O 非常簡單.這個信號將會在這個時候產生:
            1、套接字收到了一個數據報的數據包。
            2、套接字發生了異步錯誤。
                    當我們在使用 UDP 套接字異步 I/O 的時候,我們使用 recvfrom()函數來讀取數據報數據或是異步 I/O 錯誤信息。
            2.TCP 套接字的 SIGIO 信號                   (不會使用)
                      不幸的是,異步 I/O 幾乎對 TCP 套接字而言沒有什么作用。因為對于一個 TCP 套接字來說,SIGIO 信號發生的幾率太高了,所以 SIGIO 信號并不能告訴我們究竟發生了什么事情。
            在 TCP 連接中, SIGIO 信號將會在這個時候產生:
            l  在一個監聽某個端口的套接字上成功的建立了一個新連接。
            l  一個斷線的請求被成功的初始化。
            l  一個斷線的請求成功的結束。
            l  套接字的某一個通道(發送通道或是接收通道)被關閉。
            l  套接字接收到新數據。
            l  套接字將數據發送出去。

            l  發生了一個異步 I/O 的錯誤。

            一個對信號驅動 I/O 比較實用的方面是 NTP(網絡時間協議 Network Time Protocol)服務器,它使用 UDP。這個服務器的主循環用來接收從客戶端發送過來的數據報數據包,然后再發送請求。對于這個服務器來說,記錄下收到每一個數據包的具體時間是很重要的。

            因為那將是返回給客戶端的值,客戶端要使用這個數據來計算數據報在網絡上來回所花費的時間。圖 6-8 表示了怎樣建立這樣的一個 UDP 服務器。

             

             

            異步I/O模式             //比如寫操作,只需用寫,不一定寫入磁盤(這就是異步I/O)的好處。異步IO的好處效率高。
                  當我們運行在異步 I/O 模式下時,我們如果想進行 I/O 操作,只需要告訴內核我們要進行 I/O 操作,然后內核會馬上返回。具體的 I/O 和數據的拷貝全部由內核來完成,我們的程序可以繼續向下執行。當內核完成所有的 I/O 操作和數據拷貝后,內核將通知我們的程序。
            異步 I/O 和  信號驅動I/O的區別是:
                    1、信號驅動 I/O 模式下,內核在操作可以被操作的時候通知給我們的應用程序發送SIGIO 消息。

                    2、異步 I/O 模式下,內核在所有的操作都已經被內核操作結束之后才會通知我們的應用程序。

            轉自:http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520112163171778/

            亚洲中文久久精品无码ww16| 久久伊人中文无码| 久久久久久午夜成人影院| 久久久亚洲欧洲日产国码二区| 精品久久久久久亚洲精品| 99久久99久久精品国产片果冻| 久久精品成人免费观看97| 国产亚洲美女精品久久久2020| 久久久久久国产精品无码超碰| 色综合久久久久网| 麻豆av久久av盛宴av| 久久99精品国产| 亚洲香蕉网久久综合影视| www亚洲欲色成人久久精品| 东方aⅴ免费观看久久av | 亚洲精品99久久久久中文字幕| 无码人妻久久一区二区三区| 久久精品国产国产精品四凭| 久久综合狠狠综合久久综合88| 久久激情亚洲精品无码?V| 久久免费的精品国产V∧| 亚洲综合久久久| 国产成人无码精品久久久久免费| 久久久久久久97| 人妻精品久久久久中文字幕| www.久久热.com| 国产精品久久久久AV福利动漫| 亚洲国产一成久久精品国产成人综合| a级成人毛片久久| 狠狠干狠狠久久| 9久久9久久精品| 久久99国产综合精品免费| 亚洲国产精品无码久久一线| 中文字幕亚洲综合久久菠萝蜜| 精品久久人人爽天天玩人人妻| 国产精品久久久久久影院| 亚洲色大成网站WWW久久九九| 国产精品久久久久久久app| 日本亚洲色大成网站WWW久久| 国产精品亚洲综合专区片高清久久久| 久久伊人精品青青草原高清|