一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

IO的概念和5種IO模型

 xkl135 2018-06-24

一、什么是IO?

我們都知道unix世界里、一切皆文件、而文件是什么呢?文件就是一串二進制流而已、不管socket、還是FIFO、管道、終端、對我們來說、一切都是文件、一切都是流、在信息交換的過程中、我們都是對這些流進行數(shù)據(jù)的收發(fā)操作、簡稱為I/O操作(input and output)、往流中讀出數(shù)據(jù)、系統(tǒng)調用read、寫入數(shù)據(jù)、系統(tǒng)調用write、不過話說回來了、計算機里有這么多的流、我怎么知道要操作哪個流呢?做到這個的就是文件描述符、即通常所說的fd、一個fd就是一個整數(shù)、所以對這個整數(shù)的操作、就是對這個文件(流)的操作、我們創(chuàng)建一個socket、通過系統(tǒng)調用會返回一個文件描述符、那么剩下對socket的操作就會轉化為對這個描述符的操作、不能不說這又是一種分層和抽象的思想、

二、IO交互

通常用戶進程中的一個完整IO分為兩階段:

  1. 用戶空間 <-----> 內核空間、

  2. 內核空間 <-----> 設備空間、


內核空間中存放的是內核代碼和數(shù)據(jù)、而進程的用戶空間中存放的是用戶程序的代碼和數(shù)據(jù)、不管是內核空間還是用戶空間、它們都處于虛擬空間中、Linux使用兩級保護機制:0級供內核使用、3級供用戶程序使用、

操作系統(tǒng)和驅動程序運行在內核空間、應用程序運行在用戶空間、兩者不能簡單地使用指針傳遞數(shù)據(jù)、因為Linux使用的虛擬內存機制、其必須通過系統(tǒng)調用請求kernel來協(xié)助完成IO動作、內核會為每個IO設備維護一個緩沖區(qū)、用戶空間的數(shù)據(jù)可能被換出、當內核空間使用用戶空間指針時、對應的數(shù)據(jù)可能不在內存中

對于一個輸入操作來說、進程IO系統(tǒng)調用后、內核會先看緩沖區(qū)中有沒有相應的緩存數(shù)據(jù)、沒有的話再到設備中讀取、因為設備IO一般速度較慢、需要等待、內核緩沖區(qū)有數(shù)據(jù)則直接復制到進程空間、

所以、對于一個網絡輸入操作通常包括兩個不同階段:
(1)等待網絡數(shù)據(jù)到達網卡 –> 讀取到內核緩沖區(qū)
(2)從內核緩沖區(qū)復制數(shù)據(jù) –> 用戶空間

IO有內存IO、網絡IO和磁盤IO三種、通常我們說的IO指的是后兩者

三、POSIX

對IO底層交互感興趣的小伙伴可以好好了解一下POSIX(Portable Operating System Interface for Computing System)、我對深沉次原理也不怎么熟、之所以寫此篇博文也是為了后面的Java IO學習、深入淺出點到即可、此章節(jié)給有興趣的朋友一個引子、

四、IO模型

《UNIX網絡編程》說得很清楚、5種IO模型分別是阻塞IO模型、非阻塞IO模型、IO復用模型、信號驅動的IO模型、異步IO模型、前4種為同步IO操作、只有異步IO模型是異步IO操作、請仔細閱讀IO交互便于理解IO模型

(一)阻塞IO模型

當用戶進程調用了recvfrom這個系統(tǒng)調用、內核就開始了IO的第一個階段:準備數(shù)據(jù)、對于網絡IO來說、很多時候數(shù)據(jù)在一開始還沒有到達(比如、還沒有收到一個完整的UDP包)、這個時候內核就要等待足夠的數(shù)據(jù)到來、而在用戶進程這邊、整個進程會被阻塞、當內核一直等到數(shù)據(jù)準備好了、它就會將數(shù)據(jù)從內核中拷貝到用戶內存、然后返回結果、用戶進程才解除阻塞的狀態(tài)、重新運行起來、幾乎所有的程序員第一次接觸到的網絡編程都是從listen()、send()、recv()等接口開始的、這些接口都是阻塞型的、

blocking IO的特點就是在IO執(zhí)行的兩個階段(等待數(shù)據(jù)和拷貝數(shù)據(jù)兩個階段)都被阻塞了、

典型應用:阻塞Socket、Java BIO

  • 進程阻塞掛起不消耗CPU資源、及時響應每個操作

  • 實現(xiàn)難度低、開發(fā)應用較容易

  • 適用并發(fā)量小的網絡應用開發(fā)

  • 不適用并發(fā)量大的應用、因為一個請求IO會阻塞進程、所以、得為每請求分配一個處理進程(線程)以及時響應、系統(tǒng)開銷大

(二)非阻塞IO模型

當用戶進程發(fā)出read操作時、如果內核中的數(shù)據(jù)還沒有準備好、那么它并不會block用戶進程、而是立刻返回一個error、從用戶進程角度講、它發(fā)起一個read操作后、并不需要等待、而是馬上就得到了一個結果、用戶進程判斷結果是一個error時、它就知道數(shù)據(jù)還沒有準備好、于是它可以再次發(fā)送read操作、一旦內核中的數(shù)據(jù)準備好了、并且又再次收到了用戶進程的系統(tǒng)調用、那么它馬上就將數(shù)據(jù)拷貝到了用戶內存、然后返回、非阻塞的接口相比于阻塞型接口的顯著差異在于、在被調用之后立即返回、

在非阻塞式IO中、用戶進程其實是需要不斷的主動詢問kernel數(shù)據(jù)準備好了沒有

典型應用:Socket 設置 NONBLOCK

  • 進程輪詢(重復)調用、消耗CPU的資源

  • 實現(xiàn)難度低、開發(fā)應用相對阻塞IO模式較難

  • 適用并發(fā)量較小、且不需要及時響應的網絡應用開發(fā)

(三)IO復用模型

多個的進程的IO可以注冊到一個復用器(select)上、當用戶進程調用該select、select會監(jiān)聽所有注冊進來的IO、如果select所有監(jiān)聽的IO在內核緩沖區(qū)都沒有可讀數(shù)據(jù)、select調用進程會被阻塞、而當任一IO在內核緩沖區(qū)中有可數(shù)據(jù)時、select調用就會返回、而后select調用進程可以自己或通知另外的進程(注冊進程)來再次發(fā)起讀取IO、讀取內核中準備好的數(shù)據(jù)、多個進程注冊IO后、只有一個select調用進程被阻塞

IO復用相對阻塞和非阻塞更難簡單說明、所以額外解釋一段、其實IO復用模型和阻塞IO模型并沒有太大的不同、事實上、還更差一些、因為這里需要使用兩個系統(tǒng)調用(select和 recvfrom)、而阻塞IO模型只有一次系統(tǒng)調用(recvfrom)、但是、用select的優(yōu)勢在于它可以同時處理多個連接、所以如果處理的連接數(shù)不是很高的話、使用select/epoll的web server不一定比使用多線程加阻塞IO的web server性能更好、可能延遲還更大、select/epoll的優(yōu)勢并不是對于單個連接能處理得更快、而是在于能處理更多的連接

在IO復用模型中、對于每一個socket、一般都設置成為非阻塞、但是、如上圖所示、整個用戶的進程其實是一直被阻塞的、只不過進程是被select這個函數(shù)阻塞、而不是被socket IO給阻塞

典型應用:Java NIO、Nginx(epoll、poll、select)

  • 專一進程解決多個進程IO的阻塞問題、性能好、Reactor模式

  • 實現(xiàn)、開發(fā)應用難度較大

  • 適用高并發(fā)服務應用開發(fā)、一個進程/線程響應多個請求

(四)信號驅動式IO模型

信號驅動式IO就是指進程預先告知內核、向內核注冊一個信號處理函數(shù)、然后用戶進程返回不阻塞、當內核數(shù)據(jù)就緒時會發(fā)送一個信號給進程、用戶進程便在信號處理函數(shù)中調用IO讀取數(shù)據(jù)、從圖中明白實際IO內核拷貝到用戶進程的過程還是阻塞的、信號驅動式IO并沒有實現(xiàn)真正的異步、因為通知到進程之后、依然是由進程來完成IO操作、

這和后面的異步IO模型很容易混淆、需要理解IO交互并結合五種IO模型的比較閱讀

在信號驅動式IO模型中、依然不符合POSIX描述的異步IO、只能算是半異步、并且實際中并不常用、

典型應用:(不知道)

  • 回調機制、實現(xiàn)、開發(fā)應用難度大

(五)異步IO模型

用戶進程發(fā)起aio_read(POSIX異步IO函數(shù)aio_或者lio_開頭)操作之后、給內核傳遞描述符、緩沖區(qū)指針、緩沖區(qū)大小和read相同的三個參數(shù)以及文件偏移(與lseek類似)、告訴內核當整個操作完成時、如何通知我們、立刻就可以開始去做其它的事、而另一方面、從內核的角度、當它受到一個aio_read之后、首先它會立刻返回、所以不會對用戶進程產生任何阻塞、然后、內核會等待數(shù)據(jù)準備完成、然后將數(shù)據(jù)拷貝到用戶內存、當這一切都完成之后、內核會給用戶進程發(fā)送一個信號、告訴它aio_read操作完成了

異步IO的工作機制是:告知內核啟動某個操作、并讓內核在整個操作完成后通知我們、這種模型與信號驅動的IO區(qū)別在于、信號驅動IO是由內核通知我們何時可以啟動一個IO操作、這個IO操作由用戶自定義的信號函數(shù)來實現(xiàn)、而異步IO模型是由內核告知我們IO操作何時完成、

這和前面的信號驅動式IO模型很容易混淆、需要理解IO交互并結合五種IO模型的比較閱讀

在異步IO模型中、真正實現(xiàn)了POSIX描述的異步IO、是五種IO模型中唯一的異步模型

典型應用:Java 7 AIO、高性能服務器應用

  • 不阻塞、數(shù)據(jù)一步到位、Proactor模式

  • 需要操作系統(tǒng)的底層支持、LINUX 2.5 版本內核首現(xiàn)、2.6 版本產品的內核標準特性

  • 回調機制、實現(xiàn)、開發(fā)應用難度大

  • 非常適合高性能高并發(fā)應用

(六)五種IO模型的比較

  1. 阻塞IO和非阻塞IO的區(qū)別在哪?
    前面的介紹中其實已經很明確的說明了這兩者的區(qū)別、調用阻塞會一直阻塞住對應的進程直到操作完成、而非阻塞IO在內核還沒準備數(shù)據(jù)的情況下會立刻返回、阻塞和非阻塞關注的是進程在等待調用結果時的狀態(tài)、阻塞是指調用結果返回之前、當前進程會被掛起、調用進程只有在得到結果才會返回、非阻塞調用指不能立刻得到結果、該調用不會阻塞當前進程、

  2. 同步IO和異步IO區(qū)別在哪?
    兩者的區(qū)別就在于同步做IO操作的時候會將進程阻塞、按照這個定義、之前所述的阻塞IO、非阻塞IO、IO復用、信號驅動都屬于同步IO、有人可能會說、非阻塞IO并沒有被阻塞啊、這里有個非常狡猾的地方、定義中所指的IO操作是指真實的IO操作、就是例子中的recvfrom這個系統(tǒng)調用、非阻塞IO在執(zhí)行recvfrom這個系統(tǒng)調用的時候、如果內核的數(shù)據(jù)沒有準備好、這時候不會阻塞進程、但是、當內核中數(shù)據(jù)準備好的時候、recvfrom會將數(shù)據(jù)從內核拷貝到用戶內存中、這個時候進程是被阻塞了、信號驅動也是同樣的道理、在這段時間內、進程是被阻塞的、而異步IO則不一樣、當進程發(fā)起IO操作之后、就直接返回再也不理睬了、直到內核發(fā)送一個信號、告訴進程說IO完成、在這整個過程中、進程完全沒有被阻塞、

    同異步IO的根本區(qū)別在于、同步IO主動的調用recvfrom來將數(shù)據(jù)拷貝到用戶內存、而異步則完全不同、它就像是用戶進程將整個IO操作交給了他人(內核)完成、然后他人做完后發(fā)信號通知、在此期間、用戶進程不需要去檢查IO操作的狀態(tài)、也不需要主動的去拷貝數(shù)據(jù)

    POSIX的定義:
    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

  3. 信號驅動式IO和異步IO的區(qū)別?
    這里之所以單獨拿出來是因為如果還沒有清除IO概念很容易混淆、所以理解IO模型之前一定要理解IO概念、如果看完前面兩個問題、相信也能理解信號驅動IO與異步IO的區(qū)別在于啟用異步IO意味著通知內核啟動某個IO操作、并讓內核在整個操作(包括數(shù)據(jù)從內核復制到用戶緩沖區(qū))完成時通知我們、也就是說、異步IO是由內核通知我們IO操作何時完成、即實際的IO操作也是異步的、信號驅動IO是由內核通知我們何時可以啟動一個IO操作、這個IO操作由用戶自定義的信號函數(shù)來實現(xiàn)

五、總結

全篇最大的難點在于真正理解數(shù)據(jù)是如何從設備空間扭轉到內核空間再到用戶空間

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国内精品一区二区欧美| 男人和女人草逼免费视频| 国产偷拍精品在线视频| 国自产拍偷拍福利精品图片| 日韩成人h视频在线观看| 人妻亚洲一区二区三区| 欧美又大又黄刺激视频| 国产自拍欧美日韩在线观看| 久久精品亚洲精品国产欧美| 欧洲偷拍视频中文字幕| 91麻豆精品欧美视频| 欧美精品亚洲精品一区| 亚洲精品欧美精品一区三区| 日韩国产亚洲欧美另类| 成人三级视频在线观看不卡| 国产成人精品午夜福利| 色婷婷视频国产一区视频| 亚洲黄片在线免费小视频| 九九热视频经典在线观看| 中文字幕乱码免费人妻av| 欧美日韩中国性生活视频| 国产日本欧美特黄在线观看| 欧美午夜国产在线观看| 亚洲一区二区三区精选| 国内精品伊人久久久av高清| 一区二区三区国产日韩| 久久婷婷综合色拍亚洲| 国产精品一区日韩欧美| 千仞雪下面好爽好紧好湿全文| 欧美日韩综合在线精品| 夫妻性生活黄色录像视频| 亚洲专区中文字幕在线| 日韩欧美二区中文字幕| 人人爽夜夜爽夜夜爽精品视频| 亚洲性生活一区二区三区| 精品少妇一区二区视频| 亚洲第一视频少妇人妻系列| 国产精品伦一区二区三区四季| 国产传媒一区二区三区| 91亚洲国产日韩在线| 日本成人中文字幕一区|