亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

淺談帶緩沖I/O 和不帶緩沖I/O的區別與聯系

2020-01-26 14:18:07
字體:
來源:轉載
供稿:網友

這里搜集從網上看到的一些言論,自認為還是比較靠譜的,有些不靠譜的根據自己的理解進行了修正。

首先要明白不帶緩沖的概念:所謂不帶緩沖,并不是指內核不提供緩沖,而是只單純的系統調用,不是函數庫的調用。系統內核對磁盤的讀寫都會提供一個塊緩沖(在有些地方也被稱為內核高速緩存),當用write函數對其寫數據時,直接調用系統調用,將數據寫入到塊緩沖進行排隊,當塊緩沖達到一定的量時,才會把數據寫入磁盤。因此所謂的不帶緩沖的I/O是指進程不提供緩沖功能(但內核還是提供緩沖的)。每調用一次write或read函數,直接系統調用。
帶緩沖的I/O是指進程對輸入輸出流進行了改進,提供了一個流緩沖,當用fwrite函數網磁盤寫數據時,先把數據寫入流緩沖區中,當達到一定條件,比如流緩沖區滿了,或刷新流緩沖,這時候才會把數據一次送往內核提供的塊緩沖,再經塊緩沖寫入磁盤。(雙重緩沖)
因此,帶緩沖的I/O在往磁盤寫入相同的數據量時,會比不帶緩沖的I/O調用系統調用的次數要少。

看正常情況下,和磁盤交互的讀寫文件是怎么個流程!

當應用程序嘗試讀取某塊數據的時候,如果這塊數據已經存放在頁緩存中,那么這塊數據就可以立即返回給應用程序,而不需要經過實際的物理讀盤操作。當然,如果數據在應用程序讀取之前并未被存放在頁緩存中(也就是上面提到的內核高速緩存),那么就需要先將數據從磁盤讀到頁緩存中去。對于寫操作來說,應用程序也會將數據先寫到頁緩存中去(這里所說的寫到頁緩存中,如果是調用標準庫I/O進行寫,那么首先是寫到標準庫的緩沖區內,如果標準庫的緩沖區寫滿以后,在寫到頁緩沖內;如果是系統調用,那么直接寫到頁緩沖內),數據是否被立即寫到磁盤上去取決于應用程序所采用的寫操作機制:如果用戶采用的是同步寫機制,那么數據會立即被寫回到磁盤上,應用程序會一直等到數據被寫完為止;如果用戶采用的是延遲寫機制,那么應用程序就完全不需要等到數據全部被 寫回到磁盤,數據只要被寫到頁緩存中去就可以了。在延遲寫機制的情況下,操作系統會定期地將放在頁緩存中的數據刷到磁盤上。與異步寫機制不同的是,延遲寫機制在數據完全寫到磁盤上得時候不會通知應用程序,而異步寫機制在數據完全寫到磁盤上得時候是會返回給應用程序的。所以延遲寫機制本省是存在數據丟失的風險的,而異步寫機制則不會有這方面的擔心。

下面聊聊不帶緩沖的I/O

不帶緩存,不是直接對磁盤文件進行讀取操作,像read()和write()函數,它們都屬于系統調用,只不過在用戶層沒有緩存,所以叫做無緩存IO,但對于內核來說,還是進行了緩存,只是用戶層看不到罷了。

帶不帶緩存是相對來說的,如果你要寫入數據到文件上時(就是寫入磁盤上),內核先將數據寫入到內核中所設的緩沖儲存器,假如這個緩沖儲存器的長度是100個字節,你調用系統函: 

ssize_t write (int fd,const void * buf,size_t count);

寫操作時,設每次寫入長度count=10個字節,那么你幾要調用10次這個函數才能把這個緩沖區寫滿,此時數據還是在緩沖區,并沒有寫入到磁盤,緩沖區滿時才進行實際上的IO操作,把數據寫入到磁盤上,所以上面說的“不帶緩存""不是沒有緩存而是沒有直寫進磁盤就是這個意思(既然沒有寫入磁盤,調用系統調用為何可以在文件中看到寫入的內容呢,因為內核控件是共享的)

那么,既然不帶緩存的操作實際在內核是有緩存器的,那帶緩存的IO操作又是怎么回事呢?

帶緩存IO也叫標準IO,符合ANSI C 的標準IO處理,不依賴系統內核,所以移植性強,我們使用標準IO操作很多時候是為了減少對read()和write()的系統調用次數,帶緩存IO其實就是在用戶層再建立一個緩存區,這個緩存區的分配和優化長度等細節都是標準IO庫代你處理好了,不用去操心,還是用上面那個例子說明這個操作過程:

上面說要寫數據到文件上,內核緩存(注意這個不是用戶層緩存區)區長度是100字節,我們調用不帶緩存的IO函數write()就要調用10次,這樣系統效率低,現在我們在用戶層建立另一個緩存區(用戶層緩存區或者叫流緩存),假設流緩存的長度是50字節,我們用標準C庫函數的fwrite()將數據寫入到這個流緩存區里面,流緩存區滿50字節后在進入內核緩存區,再調用系統函數write()將數據寫入到內核緩沖內,如果內核緩沖也被填滿,或者內核進行fflush操作,那么內核緩沖區內數據就別寫入到文件(實質是磁盤)上,看到這里,你用該明白一點,標準IO操作fwrite()最后還是要掉用無緩存IO操作write,這里進行了兩次調用fwrite()寫100字節也就是進行兩次系統調用write()。

如果看到這里還沒有一點眉目的話,那就比較麻煩了,希望下面兩條總結能夠幫上忙:

無緩存IO操作數據流向路徑:數據――內核緩存區――磁盤

標準IO操作數據流向路徑:數據――流緩存區――內核緩存區――磁盤

下面是一個網友的見解,以供參考:

不帶緩存的I/O對文件描述符操作,下面帶緩存的I/O是針對流的。

標準I/O庫就是帶緩存的I/O,它由ANSI C標準說明。當然,標準I/O最終都會調用上面的I/O例程。標準I/O庫代替用戶處理很多細節,比如緩存分配、以優化長度執行I/O等。

標準I/O提供緩存的目的就是減少調用read和write的次數,它對每個I/O流自動進行緩存管理(標準I/O函數通常調用malloc來分配緩存)。

下面的東西是我從網上查到的對這兩者的理解,我覺得還是很到位的:

以下主要討論關于open,write等基本系統IO的帶緩沖與不帶緩沖的差別

帶緩存的文件操作是標準C庫的實現,第一次調用帶緩存的文件操作函數時標準庫會自動分配內存并且讀出一段固定大小的內容存儲在緩存中。所以以后每次的讀寫操作并不是針對硬盤上的文件直接進行的,而是針對內存中的緩存的。何時從硬盤中讀取文件或者向硬盤中寫入文件有標準庫的機制控制。不帶緩存的文件操作通常都是系統提供的系統調用, 更加低級,直接從硬盤中讀取和寫入文件,由于IO瓶頸的原因,速度并不如意,而且原子操作需要程序員自己保證,但使用得當的話效率并不差。另外標準庫中的帶緩存文件IO 是調用系統提供的不帶緩存IO實現的。

“術語不帶緩沖指的是每個read和write都調用內核中的一個系統調用。所有的磁盤I/O都要經過內核的塊緩沖(也稱內核的緩沖區高速緩存),唯一例外的是對原始磁盤設備的I/O。既然read或write的數據都要被內核緩沖,那么術語“不帶緩沖的I/O“指的是在用戶的進程中對這兩個函數不會自動緩沖,每次read或write就要進行一次系統調用?!?-------摘自<unix環境編程>

程序中用open和write打開創建并把“hello world“寫入文件test.txt,相應用fopen和fwrite操作文件test2.txt。程序執行到open和fopen之后,sleep 15秒,這時用ls查看生成了文件沒,這時用open打開的test.txt出現了,用fopen打開的的test2.txt也出現了;當程序執行完write和 fwrite之后,在15秒睡眠期間,用cat查看test.txt,其內容是“hello,world”;但是此時用cat查看test2.txt,其內容為空。睡眠結束后,執行了close(fd),此時再用cat查看test2.txt,發現其內容也有了:“hello,world”。該例子證明了open和write是不帶緩沖的,即程序一執行其io操作也立即執行,不會停留在系統提供的緩沖里,不需等到close操作完才執行。與之相比的fopen和fwrite則是帶緩沖的,(一般)要等到fclose操作完后才會執行。

相關的源碼示例如下:

#include <unistd.h>#include <iostream>#include <fcntl.h>#include <string>#include <sys/types.h>#include <sys/stat.h>using namespace std;int main(){int fd;FILE *file;char *s="hello,world/n";if((fd=open("test.txt",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1){cout<<"Error open file"<<endl;return -1;}if((file=fopen("test2.txt","w"))==NULL){cout<<"Error Open File."<<endl;return -1;}cout<<"File has been Opened."<<endl;sleep(15);if(write(fd,s,strlen(s))<strlen(s)){cout<<"Write Error"<<endl;return -1;}if(fwrite(s,sizeof(char),strlen(s),file)<strlen(s)){cout<<"Write Error in 2."<<endl;return -1;}cout<<"After write"<<endl;sleep(15);cout<<"After sleep."<<endl;close(fd);return 0;}

以 ssize_t write(int filedes, const void *buff, size_t nbytes)和size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *fp)來講講自己對unix系統下帶緩存的I/O和不帶緩存的I/O的區別。

首先要清楚一個概念,所謂的帶緩存并不是指上面兩個函數的buff參數。

當將數據寫到文件上時,內核先將該數據寫到緩存,如果該緩存未滿,則并不將其排入輸出隊列,直到緩存寫滿或者內核再次需要重新使用此緩存時才將其排入輸入隊列,待其到達隊首,再進行實際的I/O操作,也就是此時才把數據真正寫到磁盤,這種技術叫延遲寫。

現在假設內核所設的緩存是100個字節,如果你使用write,且buff的size為10,當你要把9個同樣的buff寫到文件時,你需要調用9次write,也就是9次系統調用,此時也并沒有寫到硬盤,如果想立即寫到硬盤,調用fsync,可以進行實際的I/O操作。

標準I/O,也就是帶緩存的I/O采用 FILE*,FILE實際上包含了為管理流所需要的所有信息:實際I/O的文件描述符,指向流緩存的指針(標準I/O緩存,由malloc分配,又稱為用戶態進程空間的緩存,區別于內核所設的緩存),緩存長度,當前在緩存中的字節數,出錯標志等,假設流緩存的長度為50字節,把以上的數據寫到文件,則只需要2次系統調用(fwrite調用write系統調用),因為先把數據寫到流緩存,當其滿以后或者調用fflush時才填入內核緩存,所以進行了2次的系統調用write。

fflush將流所有未寫的數據送入(刷新)到內核(內核緩沖區),fsync將所有內核緩沖區的數據寫到文件(磁盤)。至于究竟寫到了文件中還是內核緩沖區中對于進程來說是沒有差別 的,如果進程A和進程B打開同一文件,進程A寫到內核I/O緩沖區中的數據從進程B也能讀到,因為內核空間是進程共享的,
而c標準庫的I/O緩沖區則不具有這一特性,因為進程的用戶空間是完全獨立的.(個人覺得這句話非常重要)

不帶緩存的read和write是相對于 fread/fwrite等流函數來說明的,因為fread和fwrite是用戶函數(3),所以他們會在用戶層進行一次數據的緩存,而read/write是系統調用(2)所以他們在用戶層是沒有緩存的,所以稱read和write是無緩存的IO,其實對于內核來說還是進行了緩存,不過用戶層看不到罷了。

上面的內容介紹了庫緩沖機制,其中也提到了內核緩沖區這個概念,到底內核緩沖存在的價值是很么呢:

為什么總是需要將數據由內核緩沖區換到用戶緩沖區或者相反呢?

答:用戶進程是運行在用戶空間的,不能直接操作內核緩沖區的數據。 用戶進程進行系統調用的時候,會由用戶態切換到內核態,待內核處理完之后再返回用戶態

應用緩沖技術能很明顯的提高系統效率。內核與外圍設備的數據交換,內核與用戶空間的數據交換都是比較費時的,使用緩沖區就是為了優化這些費時的操作。其實核心到用戶空間的操作本身是不buffer的,是由I/O庫用buffer來優化了這個操作。比如read本來從內核讀取數據時是比較費時的,所以一次取出一塊,以避免多次陷入內核。

應用內核緩沖區的 主要思想就是一次讀入大量的數據放在緩沖區,需要的時候從緩沖區取得數據。

管理員模式和用戶模式之間的切換需要消耗時間,但相比之下,磁盤的I/O操作消耗的時間更多,為了提高效率,內核也使用緩沖區技術來提高對磁盤的訪問速度。磁盤是數據塊 的集合,內核會對磁盤上的數據塊做緩沖。內核將磁盤上的數據塊復制到內核緩沖區中,當一個用戶空間中的進程要從磁盤上讀數據時,內核一般不直接讀磁盤,而 是將內核緩沖區中的數據復制到進程的緩沖區中。當進程所要求的數據塊不在內核緩沖區時,內核會把相應的數據塊加入到請求隊列,然后把該進程掛起,接著為其 他進程服務。一段時間之后(其實很短的時間),內核把相應的數據塊從磁盤讀到內核緩沖區,然后再把數據復制到進程的緩沖區中,最后喚醒被掛起的進程。

注:理解內核緩沖區技術的原理有助于更好的掌握系統調用read&write,read把數據從內核緩沖區復制到進程緩沖區,write把數據從進程緩沖區復制到內核緩沖區,它們不等價于數據在內核緩沖區和磁盤之間的交換。

從理論上講,內核可以在任何時候寫磁盤,但并不是所有的write操作都會導致內核的寫動作。內核會把要寫的數據暫時存在緩沖區中,積累到一定數量后再一 次寫入。有時會導致意外情況,比如斷電,內核還來不及把內核緩沖區中的數據寫道磁盤上,這些更新的數據就會丟失。

應用內核緩沖技術導致的結果是:提高了磁盤的I/O效率;優化了磁盤的寫操作;需要及時的將緩沖數據寫到磁盤。

以上這篇淺談帶緩沖I/O 和不帶緩沖I/O的區別與聯系就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩欧美精品网站| 国产精品极品尤物在线观看| 国产成人久久久精品一区| 国产亚洲视频在线观看| 亚洲国产精品va在线看黑人| 91免费人成网站在线观看18| 亚洲乱码一区二区| 日韩精品欧美国产精品忘忧草| 亚洲国产欧美一区二区三区同亚洲| 色哟哟亚洲精品一区二区| 欧美极品美女视频网站在线观看免费| 精品国偷自产在线视频| 国产免费成人av| 国产精品久久久久久久久久久不卡| 久久精品国产96久久久香蕉| 亚洲人成伊人成综合网久久久| 亚洲精品videossex少妇| 一本久久综合亚洲鲁鲁| 国产丝袜一区二区三区免费视频| 亚洲欧美激情视频| 国产欧美日韩高清| 亚洲欧美日韩中文视频| 久久久久亚洲精品成人网小说| 日韩视频免费观看| 日韩久久精品成人| 最近更新的2019中文字幕| 综合欧美国产视频二区| 久久91超碰青草是什么| 国产精品极品美女粉嫩高清在线| 欧美精品在线免费观看| 日韩欧美第一页| 日韩国产欧美精品一区二区三区| 欧美一级bbbbb性bbbb喷潮片| 狠狠躁夜夜躁人人爽天天天天97| 久久免费视频网| 日本成熟性欧美| 久久精品国产久精国产一老狼| 成人免费在线视频网址| 欧美不卡视频一区发布| 中文字幕av一区中文字幕天堂| 久久99青青精品免费观看| 成人免费大片黄在线播放| 一级做a爰片久久毛片美女图片| 26uuu日韩精品一区二区| 久久精品欧美视频| 欧美激情日韩图片| 国产精品久久久久99| 国产综合久久久久久| 国产精品综合不卡av| 中文综合在线观看| www.欧美三级电影.com| 色伦专区97中文字幕| 亚洲在线免费观看| 久久久久亚洲精品国产| 91免费精品国偷自产在线| 日韩最新中文字幕电影免费看| 日韩有码在线观看| 日韩电影免费观看中文字幕| www.欧美精品一二三区| 国产精品第二页| 欧美一区二粉嫩精品国产一线天| 97高清免费视频| 国产男女猛烈无遮挡91| 91久久久精品| 午夜精品99久久免费| xvideos成人免费中文版| 日韩美女av在线免费观看| 欧美性xxxxhd| 欧美成人亚洲成人| 九九久久久久久久久激情| 国产亚洲精品久久久| 国产91精品久| 国产在线久久久| 国产一区二区三区在线免费观看| 亚洲永久在线观看| 免费97视频在线精品国自产拍| 在线视频亚洲欧美| 国产亚洲精品va在线观看| 国产精品成久久久久三级| 精品在线欧美视频| 亚洲国产精品va在线观看黑人| 久久亚洲一区二区三区四区五区高| 日韩精品极品毛片系列视频| 亚洲人成电影在线| 欧美激情欧美激情| 国产精品久久久久久久久男| 97色在线视频观看| 中文字幕亚洲综合| 中文字幕av日韩| 日韩电视剧在线观看免费网站| 久久精品国产2020观看福利| 精品magnet| 亚洲精品之草原avav久久| 亚洲国语精品自产拍在线观看| 色诱女教师一区二区三区| 国产成人中文字幕| 欧美在线国产精品| 国产精品免费电影| 精品福利在线视频| 久久精品国产视频| 日韩成人在线观看| 亚洲精品www| 久久视频精品在线| 欧美精品一二区| 色与欲影视天天看综合网| 国产mv免费观看入口亚洲| 亚洲视频欧洲视频| 久久99热这里只有精品国产| 欧美裸体xxxxx| 8090理伦午夜在线电影| 国产在线日韩在线| 中文字幕亚洲无线码在线一区| 亚洲色图激情小说| 国产精品视频一区二区三区四| 欧美日韩免费观看中文| 欧美风情在线观看| 青草青草久热精品视频在线网站| 国产精品a久久久久久| 欧美丝袜一区二区三区| 国产精品视频26uuu| 色悠久久久久综合先锋影音下载| 亚洲精品资源美女情侣酒店| 久久激情视频久久| 97视频在线观看免费高清完整版在线观看| 欧美成人免费在线观看| 欧美日韩国产一区在线| 国内免费精品永久在线视频| 久久精品国产v日韩v亚洲| 中文字幕一区二区精品| 精品久久久久久久久久久久| 久久精品国产96久久久香蕉| 久久综合五月天| 久久99热这里只有精品国产| 欧美另类69精品久久久久9999| 久久久久这里只有精品| 欧美日韩加勒比精品一区| 国产精品午夜国产小视频| 亚洲精品久久7777777| 欧美日韩xxx| 一区二区三区久久精品| 久久精品青青大伊人av| 日韩最新免费不卡| 亚洲一区美女视频在线观看免费| 亚洲一区二区免费在线| 51精品国产黑色丝袜高跟鞋| 国产精品欧美激情| 中文字幕亚洲一区在线观看| 中国人与牲禽动交精品| 日韩精品视频观看| 精品视频一区在线视频| www.久久色.com| 国模精品一区二区三区色天香| 国产亚洲欧美一区| 亚洲成人亚洲激情| 2025国产精品视频| 欧美夫妻性生活xx| 成人久久久久爱| 国产香蕉97碰碰久久人人| 欧美性猛交xxxx富婆| 欧美日韩国产999| 亚洲三级免费看| 欧美性极品少妇精品网站| 精品色蜜蜜精品视频在线观看| 久久久久久久久久婷婷|