緩衝區的個人理解!(終結版)
這個是我今天自己寫的對緩衝區的個人理解,僅是個人之間,僅供參考!
緩衝區的個人理解
這裡所說的緩衝區指的是為標準輸入與標準輸出設定的緩衝區,為什麼要設定一個標準輸入緩衝區主要是從效率上來考慮的,如果不設緩衝區會降低cpu的效率,因為它總是會等待使用者輸入完之後才會去執行某些指令!同樣設定一個標準輸出緩衝區是為了解決列印的問題!總之這樣做的目的就是為了效率!
接下來講解一下怎麼設定標準輸入與標準輸出緩衝區。
如果我們不認為的設定的話,系統會自動的為標準輸入與標準輸入設定一個緩衝區,這個緩衝區的大小通常是4Kb的大小,這和計算機中的分頁機制有關,因為程式在計算機中分配記憶體使用的就是分頁與分段的機制,並且每個頁的大小是4Kb,因此通常情況下緩衝區的大小會設定為4Kb的大小!並且這個緩衝區的型別是一個全緩衝的緩衝區!所謂全緩衝指的是:當緩衝區裡的資料寫滿的時候(或者可以說達到頂端)緩衝區中的資料才會“寫”到標準輸入磁碟檔案中,這裡說的寫不是將緩衝區中的資料移動到磁碟檔案中,而是拷貝到磁碟檔案中,也就說此時磁碟檔案中保留了一份緩衝區內容的備份!除了全緩衝外還有不緩衝和行緩衝,不緩衝不太常見與常用,在這裡我就不做講解了!下面講解一下什麼是行緩衝。行緩衝指的是當在鍵盤上敲下Enter鍵的時候資料會儲存在緩衝區中,這是毫無疑問的,同時也將緩衝區的資料拷貝一份到磁碟檔案中!那麼磁碟檔案中備份的內容有什麼用呢??本人能力有限目前還沒有發現有什麼用!
當熱我們還可以自己設定緩衝區,緩衝區的大小可以由我們自己決定,緩衝區的型別也由我們自己決定!在這裡有兩個函式,一個是setbuf( FILE *stream , char *buffer ) 另一個是setvbuf( FILE *stream , char *buffer , int mode , unsigned int size ) ;
其中緩衝區的型別可以是:_IOFBF :全緩衝 _IOLBF :行緩衝 _IONBF : 不緩衝
下面講解一下緩衝區是怎麼工作的!
當我們從鍵盤輸入資料的時候資料並不是直接被我們得到(這個問題我在上面已經講解過了,不在重複),而是將這些輸入的資料放在了緩衝區中,然後我們從緩衝區中得到我們想要的資料 !如果我們通過函式(setbuf , setvbuf)將緩衝區設定10個位元組的大小,而我們從鍵盤輸入了20個位元組大小的資料,這樣我們輸入的前10個資料會放在緩衝區中,因為我們設定的緩衝區的大小隻能夠裝下10個位元組大小的資料,裝不下20個位元組大小的資料。那麼剩下的那10個位元組大小的資料怎麼辦呢??暫時放在了輸入流中!如果不能夠理解這個,那我舉一個比較形象的例子:
(圖片在我發的附件中)
上面的箭頭表示的區域就相當是一個輸入流,紅色的地方相當於一個開關,這個開關可以控制往深綠色區域(標註的是緩衝區)裡放進去的資料,輸入20個位元組的資料只往緩衝區中放進去了10個位元組,剩下的10個位元組的資料就被停留在了輸入流裡!等待下去往緩衝區中放入!接下來系統是如何來控制這個緩衝區呢?
在C語言方式下 是一個結構體陣列 型別是FILE結構體
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
結構體中的成員簡單的介紹下
_ptr //指向當前緩衝區內容的指標
_cnt //如果是輸入緩衝區 那他就是顯示現在緩衝區裡還有多少個有效資料
_base //緩衝區基地址
_flag //標誌位 具體好像就是什麼可寫啊 可讀啊之類的
_file //這個是裝置控制程式碼(也可以說是檔案控制程式碼)
_bufsiz //緩衝區總大小 一般都是0x1000 也就是4k 也就是一個分頁
在上面我們向緩衝區中放入了10個位元組大小的資料,FILE結構體中的_cnt變為了10 ,說明此時緩衝區中有10個位元組大小的資料可以讀,同時我們假設緩衝區的基地址也就是_base是0x00428e60 ,它是不變的 ,而此時_ptr的值也為0x00428e60 ,表示從0x00428e60這個位置開始讀取資料,當我們從緩衝區中讀取5個資料的時候,_cnt變為了5 ,表示緩衝區中還有5個資料可以讀,_ptr則變為了0x00428e65表示下次應該從這個位置開始讀取緩衝區中的資料 ,如果接下來我們再讀取5個資料的時候,_cnt則變為了0 ,表示緩衝區中已經沒有任何資料了,_ptr變為了0x00428e69表示下次應該從這個位置開始從緩衝區中讀取資料,但是此時緩衝區中已經沒有任何資料了,所以要將輸入流中的剩下的那10個資料放進來,這樣緩衝區中又有了10個資料,此時_cnt變為了10 ,注意了剛才我們講到_ptr的值是0x00428e69 ,而當緩衝區中重新放進來資料的時候這個_ptr的值變為了0x00428e60 ,這是因為當緩衝區中沒有任何資料的時候要將_ptr這個值進行一下重新整理,使其指向緩衝區的基地址也就是0x00428e60這個值!因為下次要從這個位置開始讀取資料!
在這裡有點需要說明:當我們從鍵盤輸入字串的時候需要敲一下Enter鍵才能夠將這個字串送入到緩衝區中,那麼敲入的這個Enter鍵(\r)會被轉換為一個換行符\n,這個換行符\n也會被儲存在緩衝區中並且被當成一個字元來計算!比如我們在鍵盤上敲下了123456這個字串,然後敲一下Enter鍵(\r)將這個字串送入了緩衝區中,那麼此時緩衝區中的位元組個數是7 ,而不是6。
緩衝區的重新整理就是將指標_ptr變為緩衝區的基地址 ,同時_cnt的值變為0 ,因為緩衝區重新整理后里面是沒有資料的!
緩衝區的個人理解
這裡所說的緩衝區指的是為標準輸入與標準輸出設定的緩衝區,為什麼要設定一個標準輸入緩衝區主要是從效率上來考慮的,如果不設緩衝區會降低cpu的效率,因為它總是會等待使用者輸入完之後才會去執行某些指令!同樣設定一個標準輸出緩衝區是為了解決列印的問題!總之這樣做的目的就是為了效率!
接下來講解一下怎麼設定標準輸入與標準輸出緩衝區。
如果我們不認為的設定的話,系統會自動的為標準輸入與標準輸入設定一個緩衝區,這個緩衝區的大小通常是4Kb的大小,這和計算機中的分頁機制有關,因為程式在計算機中分配記憶體使用的就是分頁與分段的機制,並且每個頁的大小是4Kb,因此通常情況下緩衝區的大小會設定為4Kb的大小!並且這個緩衝區的型別是一個全緩衝的緩衝區!所謂全緩衝指的是:當緩衝區裡的資料寫滿的時候(或者可以說達到頂端)緩衝區中的資料才會“寫”到標準輸入磁碟檔案中,這裡說的寫不是將緩衝區中的資料移動到磁碟檔案中,而是拷貝到磁碟檔案中,也就說此時磁碟檔案中保留了一份緩衝區內容的備份!除了全緩衝外還有不緩衝和行緩衝,不緩衝不太常見與常用,在這裡我就不做講解了!下面講解一下什麼是行緩衝。行緩衝指的是當在鍵盤上敲下Enter鍵的時候資料會儲存在緩衝區中,這是毫無疑問的,同時也將緩衝區的資料拷貝一份到磁碟檔案中!那麼磁碟檔案中備份的內容有什麼用呢??本人能力有限目前還沒有發現有什麼用!
當熱我們還可以自己設定緩衝區,緩衝區的大小可以由我們自己決定,緩衝區的型別也由我們自己決定!在這裡有兩個函式,一個是setbuf( FILE *stream , char *buffer ) 另一個是setvbuf( FILE *stream , char *buffer , int mode , unsigned int size ) ;
其中緩衝區的型別可以是:_IOFBF :全緩衝 _IOLBF :行緩衝 _IONBF : 不緩衝
下面講解一下緩衝區是怎麼工作的!
當我們從鍵盤輸入資料的時候資料並不是直接被我們得到(這個問題我在上面已經講解過了,不在重複),而是將這些輸入的資料放在了緩衝區中,然後我們從緩衝區中得到我們想要的資料 !如果我們通過函式(setbuf , setvbuf)將緩衝區設定10個位元組的大小,而我們從鍵盤輸入了20個位元組大小的資料,這樣我們輸入的前10個資料會放在緩衝區中,因為我們設定的緩衝區的大小隻能夠裝下10個位元組大小的資料,裝不下20個位元組大小的資料。那麼剩下的那10個位元組大小的資料怎麼辦呢??暫時放在了輸入流中!如果不能夠理解這個,那我舉一個比較形象的例子:
(圖片在我發的附件中)
上面的箭頭表示的區域就相當是一個輸入流,紅色的地方相當於一個開關,這個開關可以控制往深綠色區域(標註的是緩衝區)裡放進去的資料,輸入20個位元組的資料只往緩衝區中放進去了10個位元組,剩下的10個位元組的資料就被停留在了輸入流裡!等待下去往緩衝區中放入!接下來系統是如何來控制這個緩衝區呢?
在C語言方式下 是一個結構體陣列 型別是FILE結構體
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
結構體中的成員簡單的介紹下
_ptr //指向當前緩衝區內容的指標
_cnt //如果是輸入緩衝區 那他就是顯示現在緩衝區裡還有多少個有效資料
_base //緩衝區基地址
_flag //標誌位 具體好像就是什麼可寫啊 可讀啊之類的
_file //這個是裝置控制程式碼(也可以說是檔案控制程式碼)
_bufsiz //緩衝區總大小 一般都是0x1000 也就是4k 也就是一個分頁
在上面我們向緩衝區中放入了10個位元組大小的資料,FILE結構體中的_cnt變為了10 ,說明此時緩衝區中有10個位元組大小的資料可以讀,同時我們假設緩衝區的基地址也就是_base是0x00428e60 ,它是不變的 ,而此時_ptr的值也為0x00428e60 ,表示從0x00428e60這個位置開始讀取資料,當我們從緩衝區中讀取5個資料的時候,_cnt變為了5 ,表示緩衝區中還有5個資料可以讀,_ptr則變為了0x00428e65表示下次應該從這個位置開始讀取緩衝區中的資料 ,如果接下來我們再讀取5個資料的時候,_cnt則變為了0 ,表示緩衝區中已經沒有任何資料了,_ptr變為了0x00428e69表示下次應該從這個位置開始從緩衝區中讀取資料,但是此時緩衝區中已經沒有任何資料了,所以要將輸入流中的剩下的那10個資料放進來,這樣緩衝區中又有了10個資料,此時_cnt變為了10 ,注意了剛才我們講到_ptr的值是0x00428e69 ,而當緩衝區中重新放進來資料的時候這個_ptr的值變為了0x00428e60 ,這是因為當緩衝區中沒有任何資料的時候要將_ptr這個值進行一下重新整理,使其指向緩衝區的基地址也就是0x00428e60這個值!因為下次要從這個位置開始讀取資料!
在這裡有點需要說明:當我們從鍵盤輸入字串的時候需要敲一下Enter鍵才能夠將這個字串送入到緩衝區中,那麼敲入的這個Enter鍵(\r)會被轉換為一個換行符\n,這個換行符\n也會被儲存在緩衝區中並且被當成一個字元來計算!比如我們在鍵盤上敲下了123456這個字串,然後敲一下Enter鍵(\r)將這個字串送入了緩衝區中,那麼此時緩衝區中的位元組個數是7 ,而不是6。
緩衝區的重新整理就是將指標_ptr變為緩衝區的基地址 ,同時_cnt的值變為0 ,因為緩衝區重新整理后里面是沒有資料的!
相關文章
- C 標準庫IO緩衝區和核心緩衝區的區別
- 緩衝區分析
- Java NIO:緩衝區Java
- getchar緩衝區
- 結合php ob函式理解緩衝機制PHP函式
- PHP的輸出緩衝區PHP
- Java NIO 之緩衝區Java
- Unity深度緩衝區指令Unity
- Java整數緩衝區Java
- nginx 緩衝區構造Nginx
- stdio流緩衝區
- Node.js Buffer(緩衝區)Node.js
- JavaScript WebGL 幀緩衝區物件JavaScriptWeb物件
- Linux 命令 管道 緩衝區Linux
- log buffer(日誌緩衝區)
- Java NIO 之 Buffer(緩衝區)Java
- Java NIO2:緩衝區Java
- 動態更新——緩衝區物件物件
- 緩衝區溢位實驗
- RMAN的IO記憶體緩衝區記憶體
- 緩衝區溢位小程式分析
- PHP 輸出緩衝區應用PHP
- Java-NIO之Buffer(緩衝區)Java
- Redis效能篇(五)Redis緩衝區Redis
- 8、Node.js Buffer(緩衝區)Node.js
- node.js中緩衝區–BufferNode.js
- C語言緩衝區問題C語言
- WebGIS 8-1 緩衝區分析Web
- cuug 資料緩衝區調優
- Buffer Cache Size(資料緩衝區)
- gets()getchar()與緩衝區的問題
- Java NIO -- 緩衝區(Buffer)的資料存取Java
- 使用edit編輯緩衝區中的sqlSQL
- 調節Oracle資料緩衝區引數,緩衝整個資料庫(轉)Oracle資料庫
- MySQL中讀頁緩衝區buffer poolMySql
- 《Lua-in-ConTeXt》10:緩衝區魔法Context
- Java NIO 緩衝區學習筆記Java筆記
- C語言清空輸入緩衝區C語言