1. 程式人生 > >關於緩衝區/池設計中的三個佇列

關於緩衝區/池設計中的三個佇列

今天在看作業系統相關的書,看到一個例子:用三個佇列來管理緩衝區池的使用情況,三個佇列分別為:空閒緩衝佇列em,輸入緩衝佇列in,輸出緩衝佇列out。

 

對緩衝不是很瞭解,只知道緩衝是用來平衡不同裝置資料傳輸速度的差異的,對於其具體實現不是很瞭解。其實緩衝區用一個位元組陣列就可以實現,當然其中也設計到許多具體的設計問題。今天我想記錄的和執行緒池類似的東西,那就是緩衝區池。為了減少緩衝區建立和刪除的效率問題,採用緩衝池技術,當需要緩衝區的時候,直接從池中取出空閒的緩衝區使用,當使用結束的時候,清空緩衝區內容並放回池中。

 

而這三個佇列有什麼用呢?先說說緩衝池有哪些需要知道的方法吧。

第一個是add_buf ( type , numb ),用於把緩衝區numb插入type型別的佇列中(比如輸入緩衝區佇列)。響應的,就有有take_buf ( type , numb),從type型別的佇列中取出緩衝區numb。

 

使用這幾個操作,緩衝池的工作過程可描述如下:

首先,輸入程序呼叫take_buf (em,numb)過程從空白緩衝區佇列中取出一個緩衝號為numb的空白緩衝區,將其作為收容輸入緩衝區hin,當hin中裝滿了由輸入裝置輸入的資料之後,系統呼叫過程add_buf (in,hin)將該緩衝區插入輸入緩衝區佇列in中

另外,當程序需要輸出資料資料時,輸出程序經過緩衝管理程式呼叫過程take_buf(em,numb)從空白緩衝區佇列中取出一個空白緩衝區numb作為收容輸出緩衝區hout,待hout中裝滿輸出資料之後,系統再呼叫過程add_buf(out,hout)將該緩衝區插入輸出緩衝區佇列out.

  對緩衝區的輸入資料和輸出資料的提取也是由過程add_buf和take_buf實現的。take_buf(out,numb)從輸出緩衝佇列中取出裝滿輸出資料的緩衝區number,將其作為sout。當sout中資料輸出完畢時,系統呼叫過程add_buf(em,sout)將該緩衝區插入空白緩衝佇列。而take_buf(in,number)則從輸入緩衝佇列中取出一個裝滿輸入資料的緩衝區numb作為輸入緩衝區sin,當CPU從中提取完所需資料之後,系統呼叫過程add_buf(em,sin)將該緩衝區釋放和插入空白緩衝佇列em中。

 

另外,關於緩衝池,還涉及到一個多執行緒/程序互斥操作的問題。我們可以用訊號量來實現多執行緒/程序對任一佇列的互斥操作

這裡採用程序IPC的P、V原語,用訊號量s代表任一佇列的可用緩衝區個數,假定上面三個佇列的初值分別為n1,n2,n3,同時引入一個互斥使用任一佇列的訊號量mutex,初始值為1.

然後我們實現get_buf(type , numb)和put_buf(type,numb),他們呼叫了上面用到的take_buf方法和add_buf方法,虛擬碼實現如下:

get_buf(type,numb)
begin
    P(s)
    P(mutex)
    numb = take_buf(type,numb)
    V(mutex)
end
put_buf(type,numb)
begin
    P(mutex)
    add_buf(type,numb)
    V(mutex)
    V(s)
end