• <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操作默認(rèn)是阻塞I/O,即open和socket創(chuàng)建的I/O都是阻塞I/O)
            【2】        非阻塞 I/O        (可以通過fcntl或者open時(shí)使用O_NONBLOCK參數(shù),將fd設(shè)置為非阻塞的I/O)
            【3】        I/O 多路復(fù)用     (I/O多路復(fù)用,通常需要非阻塞I/O配合使用)
            【4】        信號驅(qū)動 I/O    (SIGIO)
            【5】        異步 I/O

             

            一般來說,程序進(jìn)行輸入操作有兩步:
            1.等待有數(shù)據(jù)可以讀
            2.將數(shù)據(jù)從系統(tǒng)內(nèi)核中拷貝到程序的數(shù)據(jù)區(qū)。

            對于sock編程來說:

                     第一步:   一般來說是等待數(shù)據(jù)從網(wǎng)絡(luò)上傳到本地。當(dāng)數(shù)據(jù)包到達(dá)的時(shí)候,數(shù)據(jù)將會從網(wǎng)絡(luò)層拷貝到內(nèi)核的緩存中;

                     第二步:   是從內(nèi)核中把數(shù)據(jù)拷貝到程序的數(shù)據(jù)區(qū)中。

             

            阻塞I/O模式                            //進(jìn)程處于阻塞模式時(shí),讓出CPU,進(jìn)入休眠狀態(tài)
                    阻塞 I/O 模式是最普遍使用的 I/O 模式。是Linux系統(tǒng)下缺省的IO模式。

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

                   一個(gè)套接字建立后所處于的模式就是阻塞 I/O 模式。(因?yàn)長inux系統(tǒng)默認(rèn)的IO模式是阻塞模式)


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

                   一個(gè)進(jìn)程調(diào)用 recvfrom  ,然后系統(tǒng)調(diào)用并不返回知道有數(shù)據(jù)報(bào)到達(dá)本地系統(tǒng),然后系統(tǒng)將數(shù)據(jù)拷貝到進(jìn)程的緩存中。 (如果系統(tǒng)調(diào)用收到一個(gè)中斷信號,則它的調(diào)用會被中斷)

               我們稱這個(gè)進(jìn)程在調(diào)用recvfrom一直到從recvfrom返回這段時(shí)間是阻塞的。當(dāng)recvfrom正常返回時(shí),我們的進(jìn)程繼續(xù)它的操作。

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

            非阻塞模式I/O                           //非阻塞模式的使用并不普遍,因?yàn)榉亲枞J綍速M(fèi)大量的CPU資源。
                   當(dāng)我們將一個(gè)套接字設(shè)置為非阻塞模式,我們相當(dāng)于告訴了系統(tǒng)內(nèi)核: “當(dāng)我請求的I/O 操作不能夠馬上完成,你想讓我的進(jìn)程進(jìn)行休眠等待的時(shí)候,不要這么做,請馬上返回一個(gè)錯(cuò)誤給我。”
                  我們開始對 recvfrom 的三次調(diào)用,因?yàn)橄到y(tǒng)還沒有接收到網(wǎng)絡(luò)數(shù)據(jù),所以內(nèi)核馬上返回一個(gè) EWOULDBLOCK的錯(cuò)誤。

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

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

            I/O多路復(fù)用                             //針對批量IP操作時(shí),使用I/O多路復(fù)用,非常有好。

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

                   多路復(fù)用的高級之處在于::

                          它能同時(shí)等待多個(gè)文件描述符,而這些文件描述符(套接字描述符)其中的任意一個(gè)進(jìn)入讀就緒狀態(tài),select()函數(shù)就可以返回。

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

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


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

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

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

            1.UDP 套接字的 SIGIO 信號                    (比較簡單)
            在 UDP 協(xié)議上使用異步 I/O 非常簡單.這個(gè)信號將會在這個(gè)時(shí)候產(chǎn)生:
            1、套接字收到了一個(gè)數(shù)據(jù)報(bào)的數(shù)據(jù)包。
            2、套接字發(fā)生了異步錯(cuò)誤。
                    當(dāng)我們在使用 UDP 套接字異步 I/O 的時(shí)候,我們使用 recvfrom()函數(shù)來讀取數(shù)據(jù)報(bào)數(shù)據(jù)或是異步 I/O 錯(cuò)誤信息。
            2.TCP 套接字的 SIGIO 信號                   (不會使用)
                      不幸的是,異步 I/O 幾乎對 TCP 套接字而言沒有什么作用。因?yàn)閷τ谝粋€(gè) TCP 套接字來說,SIGIO 信號發(fā)生的幾率太高了,所以 SIGIO 信號并不能告訴我們究竟發(fā)生了什么事情。
            在 TCP 連接中, SIGIO 信號將會在這個(gè)時(shí)候產(chǎn)生:
            l  在一個(gè)監(jiān)聽某個(gè)端口的套接字上成功的建立了一個(gè)新連接。
            l  一個(gè)斷線的請求被成功的初始化。
            l  一個(gè)斷線的請求成功的結(jié)束。
            l  套接字的某一個(gè)通道(發(fā)送通道或是接收通道)被關(guān)閉。
            l  套接字接收到新數(shù)據(jù)。
            l  套接字將數(shù)據(jù)發(fā)送出去。

            l  發(fā)生了一個(gè)異步 I/O 的錯(cuò)誤。

            一個(gè)對信號驅(qū)動 I/O 比較實(shí)用的方面是 NTP(網(wǎng)絡(luò)時(shí)間協(xié)議 Network Time Protocol)服務(wù)器,它使用 UDP。這個(gè)服務(wù)器的主循環(huán)用來接收從客戶端發(fā)送過來的數(shù)據(jù)報(bào)數(shù)據(jù)包,然后再發(fā)送請求。對于這個(gè)服務(wù)器來說,記錄下收到每一個(gè)數(shù)據(jù)包的具體時(shí)間是很重要的。

            因?yàn)槟菍⑹欠祷亟o客戶端的值,客戶端要使用這個(gè)數(shù)據(jù)來計(jì)算數(shù)據(jù)報(bào)在網(wǎng)絡(luò)上來回所花費(fèi)的時(shí)間。圖 6-8 表示了怎樣建立這樣的一個(gè) UDP 服務(wù)器。

             

             

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

                    2、異步 I/O 模式下,內(nèi)核在所有的操作都已經(jīng)被內(nèi)核操作結(jié)束之后才會通知我們的應(yīng)用程序。

            轉(zhuǎn)自:http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520112163171778/

            久久美女人爽女人爽| 久久91亚洲人成电影网站| 久久福利青草精品资源站免费| 久久久久久久综合日本| 国产2021久久精品| 久久激情五月丁香伊人| 99久久国产综合精品麻豆| 久久精品国产亚洲欧美| 国产婷婷成人久久Av免费高清| 国产精品一区二区久久不卡| 99久久精品免费看国产一区二区三区| 亚洲中文久久精品无码| 伊人久久一区二区三区无码| 性高湖久久久久久久久| 久久99精品国产一区二区三区| 99国产精品久久| 99久久99久久精品国产片| 中文字幕无码久久精品青草| 中文字幕无码av激情不卡久久| 久久久精品久久久久影院| 亚洲精品美女久久777777| 久久精品水蜜桃av综合天堂| 久久精品成人| 一本久道久久综合狠狠躁AV| 久久久久亚洲精品日久生情| 99久久精品国产毛片| 久久无码人妻精品一区二区三区 | 久久国产热这里只有精品| 久久久99精品成人片中文字幕| 日韩影院久久| 久久国产精品久久国产精品| 精品国产青草久久久久福利| 久久久久久国产精品无码超碰| 国产国产成人精品久久| 久久久久久亚洲精品不卡| 99精品久久久久久久婷婷 | 免费一级欧美大片久久网| 伊人伊成久久人综合网777| 思思久久好好热精品国产| 国产精品福利一区二区久久| 欧美精品丝袜久久久中文字幕|