在現代操做系統裏幾乎全部的I/O設備在和處理機交換數據時都使用了緩衝機制,緩衝區是一個存儲區域,能夠是專門的硬件寄存器組成可是由於硬件的成本較高容量也小,通常的狀況下,更多的利用內存來做爲緩衝區。linux
緩衝區管理:組織緩衝區並提供得到和釋放緩衝區的手段。小程序
緩衝技術是爲了協調吞吐速度相差很大的設備之間數據調用而採用的技術ide
緩衝的引用要解決的問題實際上有:
函數
一、改善CPU和I/O設備之間速度不匹配的狀況。學習
二、能夠減小I/O設備對CPU的中斷次數及放寬對CPU的中斷響應時間要求。spa
三、提升CPU和I/O設備之間的並行性
操作系統
eg: 在生產者(CPU)和消費者(打印機)之間設置緩衝區,生產者在生產了一批數據並將其入緩衝區接着投入下一次生產,而消費此時就可拿出數據,這樣生產者和消費者就可處於並行的工做狀態。若是他們之間沒有緩衝區的話,生產者生產好了一批數據以後必須停下工做等待消費者,這樣會使得生產者的效率下降。
指針
一、單緩衝區orm
假設數據從I/O設備傳遞給緩衝區的時間爲T,CPU對數據的處理時間是C,緩衝區將數據傳送給CPU的時間是M,那麼憂鬱在I/O設備給緩衝區傳送數據時,CPU能夠同時處理數據,因此係統對數據處理的總時間爲Max(C,T)+M.blog
**在字符設備輸入時緩衝區是用於暫存用戶輸入的一行數據,在輸入期間用戶進程掛起等待,輸出時,用戶進程將一行數據輸入到緩衝區後繼續進行處理,當用戶程序已有第二行數據輸出可是第一行數據還沒有被提取完成則會形成用戶進程的阻塞。
2.雙緩衝區
雙緩衝區其實是爲了解決消費者和生產者在使用緩衝區時互斥的問題。若是消費者還沒有取走緩衝區的數據,那麼即便生產者產生了新數據也沒法送入緩衝區
雙緩衝又被稱爲緩衝對換,在設備如屬實可將數據先送入第一緩衝區,等到第一緩衝區裝滿後轉向第二緩衝區,此時操做系統就能夠從第一緩衝區移出數據送入用戶進程,讓CPU對數據進行處理。
若是在實現兩臺機器之間通訊時他們只設置了單緩衝,那麼他們之間只能在任一時刻實現單向數據傳輸,爲了實現雙向數據傳輸必須在每一個機器上分別設置發送緩衝區及接收緩衝區。
3.環形緩衝區
環形緩衝區中包含多個緩衝區,其中每一個緩衝的大小相同,而且被分爲三種類型:
R:裝輸入數據
G:已裝滿數據的緩衝區
C:進程正在使用的緩衝區
環形緩衝區裏含有三個指針:
Nexti:指向輸入進程下次可用的R
Nxetg:指向計算進程下次可以使用的G
Cuurent:指向進程正在使用的緩衝區
在對環形緩衝區進行處理的時候有兩個重要的方法:
1.Getbuf:將指針Nextg指向的緩衝區提供給進程而且讓修改current的值,最後讓Nextg指向下一個G緩衝區
2.Releasebuf:將使用完成的C緩衝區釋放將其修改爲R,當R緩衝區滿時將其修改成G
環形緩衝區還會出現下面兩種問題:
1.系統計算受限:Nexti追上Nextg
2.系統I/O受限:Nextg追上Nexti
緩衝池
咱們在以前所說的緩衝區均可以稱爲專用緩衝。當系統較大時,爲了提升利用率,咱們使用便可輸入又可輸出的公用緩衝池,在池中設置若干個緩衝區。
緩衝池的組成:
1.空白緩衝隊列:空緩衝區所鏈成
2.輸入隊列:裝滿輸入數據的緩衝區鏈成
3.輸出隊列:裝滿輸出數據的緩衝區鏈成
緩衝區的工做方式:收容輸入、收容輸出、提取輸入、提取輸出
在咱們的學習過程當中你們實際上已經和緩衝很熟悉了可是咱們卻視若無睹,咱們知道在linux裏有三種緩衝機制,行緩衝,全緩衝,無緩衝。
全緩衝:直到緩衝區填滿以後調用系統I/O
行緩衝:直到遇到換行或者行緩衝填滿以後進行調用系統I/O
咱們來看兩個關於行緩衝的例子:
第一例:神祕消失的hello world
在上面的程序裏咱們沒有在標準輸出裏使用‘\n’而且使用了_exit(0)致使行緩衝的內容沒有被處理
因此在咱們運行程序時,咱們並無看見hello world
**
exit ()。調用exit函數以後,它首先會執行一系列的清理處理,包括調用執行各終止處理程序,關閉全部標準IO流等,而後進入內核。
_exit ()。與exit不一樣的是,它不進行清理工做而直接進入內核。
_Exit ()。一樣,它也不進行清理工做而直接進入內核。
第二例:進度條小程
顯然在此例裏,咱們藉助了fflush來刷新咱們的緩衝區,在使用該函數時不管緩衝區是否被填滿都會調用系統I/O。
再此咱們須理解換行和回車的不一樣概念,換行是指跳到當前行的下一行,而回車是指回到該行的行首,此例中咱們使用了‘\r’來控制每次從行首的覆蓋輸出實現進度條的前進,是否是很神奇呢,你也快去試一試吧!