数据缓冲区高速缓冲
數據緩沖區高速緩沖
緩沖頭部
一個緩沖區有兩部分組成:一個含有磁盤上數據的存儲數組和一個標識該緩
沖區的緩沖頭部。
一個緩沖區的數據與文件系統上一個邏輯磁盤塊中的數據相對應,并且通過
考察緩沖頭部中的標識字段來識別緩沖區內容。緩沖區是磁盤塊在主存中的拷貝,
磁盤塊的內容映射到緩沖區中。但是同一時刻,一個磁盤塊不能映射到多個緩沖
區中。
設備號字段和塊號字段指明了文件系統和磁盤上數據的塊號,唯一地標識了
該緩沖區。設備號是邏輯文件系統號,不是物理設備號。緩沖區的數據部分必須
大于等于磁盤塊的大小。
緩沖區的狀態是有下列條件的組合:
1)緩沖區當前為“上鎖”(忙)
2)緩沖區包含有效數據
3)內核把某緩沖區重新分配出去之前必須把該緩沖區內容寫到磁盤上(延遲寫)
4)內核當前正從磁盤往緩沖區讀信息或把緩沖區的內容寫到磁盤上
5)一個進程當前正在等候緩沖區變為閑。
緩沖池
內核按照最近最少使用算法把數據緩存于緩沖池中,內核維護一個緩沖區的
空閑表(雙向鏈表),它保存最近被使用的次序。離空閑表最近的緩沖區比離空
閑表頭遠的緩沖區是最近最少使用的。
散列隊列
內核把緩沖區組織成一個個隊列,這些隊列是按照設備號和塊號散列的。內
核把一個散列隊列上的緩沖區鏈接成一個個類似空閑表結構的雙向鏈接循環表,
內核使用的散列函數也是簡單的,這樣保證性能。
一個緩沖區必須在散列隊列里面,也可以在空閑表中。
緩沖區的檢索
若果一個進程想要都一個文件中的數據,則內核需要判定數據在哪個文件系統
的哪個塊上。當要從一個特定的磁盤上讀取數據時,內核檢測數據是否在緩沖區上,
若是在就直接可以從緩沖區上讀取數據;否則,分一個空閑緩沖區。
讀寫磁盤塊--算法getblk
內核給緩沖區分配磁盤塊時,可能出現五種情況:
1)內核在散列隊列找到該塊,并且它的緩沖區是空閑的
2)內核在散列隊列中找不到該塊,因此,從空閑表中分配一個緩沖區
3)內核在散列隊列中找不到該塊,試圖從空閑表中分配一個緩沖區的時候,
在空閑表中找到一個已經表上“延遲寫”標記的緩沖區。內核必須該緩沖區的
內容寫到磁盤上,并分配另外一個緩沖區。
4)內核在散列隊列中找不到該塊,并且空閑表已空。
5)內核在散列隊列中找到該塊,但是它的緩沖區為忙。
算法:getblk 輸入:文件系統號 塊號 輸出:現在能被磁盤塊使用的上了鎖的緩沖區 {while(沒有找到緩沖區){if(塊在散列隊列中){if(塊忙){/*第5種情況*/sleep(等待“緩沖區變為空閑”事件);continue;}為緩沖區標記上“忙”;從空閑表中摘下緩沖區;return (緩沖區);}else{if(空閑表中沒有緩沖區){/*第4種情況*/sleep(等待“任何緩沖區變為空閑”事件);continue;}從空閑表中摘下緩沖區;if(緩沖區標記著延遲寫){/*第3種情況*/把緩沖區異步寫到磁盤上;continue;}從舊散列隊列中摘下緩沖區;把緩沖區投入新散列隊列;return (緩沖區);}} }
釋放緩沖區算法brelse
算法:brelse 輸入:上鎖態的緩沖區 輸出:無 {喚醒正在等待緩沖區變為空閑的所有進程;喚醒正在等待任何緩沖區變為空閑的所有進程;提高處理機執行級以封鎖中斷;if(緩沖區所有內容有效且緩沖區非舊)將緩沖區送入空閑表尾部else將緩沖區送入空閑表頭部降低處理機執行級以允許中斷;給緩沖區解鎖;}
情況1:內核搜索塊4的實例圖
? ? ? ?圖--在散列隊列上搜索塊4
? ? ? ? 圖--從空閑表上摘下第4塊
情況2:從緩沖區上找第21塊
圖--在緩沖區上搜索第21塊
圖--從空閑表中摘下第一個緩沖區,分配給第21塊
重新給該塊的緩沖區安置在相應的散列隊列里面。
情況3:內核必須從空閑表中分配到一個緩沖區。
從空閑表中摘下的緩沖區已經被標上“延遲寫”,因此,它必須在使用該緩沖區之前,
將緩沖區的內容寫到磁盤上。內核開始了一個異步寫,并且試圖從空閑表上分配到
另外一個緩沖區。當異步寫完成時,內核把該緩沖區釋放,并把它放到空閑表的首部。
? ? ? ? 圖-- 搜索第21塊,空閑表上頭兩個緩沖區標記著延遲寫
圖--寫第3塊、第5塊,把第4塊的緩沖區分配該第21塊
情況4:散列隊列找不到該塊,并且空閑表為空
進程A進入睡眠狀態,直到有另外一個進程執行算法brelse,釋放一個緩沖區。當內核
調度到進程A時,它必須重新為該塊重新搜索散列隊列,此舉保證僅有一個緩沖區包含
該塊。
情況5:進程B等待進程A正在使用的塊(忙),進程B將進入睡眠狀態
進程A執行算法brelse,釋放該緩沖區,這時將喚醒”緩沖區變為空閑“上睡眠的所
有進程,包括進程B。當內核調度到進程B執行時,進程B需要再次搜索該磁盤塊。
總結
- 上一篇: Vectorcast 2021 sp4
- 下一篇: C语言程序设计第五版谭浩强 第七章答案