迴圈緩衝區

2021-08-21 18:48:25 字數 1786 閱讀 9459

這次需要記錄之前了解到的參考自linux核心迴圈佇列kfifo的迴圈緩衝區實現方法。

1、迴圈緩衝區的實現依靠佇列來實現,也就是分配乙個陣列來儲存實際資料。

2、對於乙個迴圈緩衝區來說,我們需要關注的點有:

①緩衝區大小應該設定多少?

②緩衝區隊頭(in)、隊尾(out)初始值?

③緩衝區什麼時候為空,什麼時候為滿?

④如何表示緩衝區長度?

⑤如何入隊,如何出隊?

⑥如何處理索引值溢位問題?

3、要實現迴圈緩衝區,我們當然可以用我們資料結構課學過的迴圈佇列來實現,也就是:

設佇列大小為m;in和out為下標值。

①迴圈緩衝區的大小設定為m(沒有限制)

②初始化隊頭 in=0 ,隊尾 out = 0

③out == in的時候緩衝區為空,(in+1)%m == out 的時候為滿

④緩衝區長度len =(in - out + m)% m

⑤入隊:a[in] = data ;  in = (in+1) % m;

出隊:data = a[out] ;  out = (out+1)%m;

⑥索引溢位通過對緩衝區長度進行求餘來實現。

4、我們也可以通過另一種更好的方法來實現

同樣設佇列大小為m;in和out為下標值,但是他們的資料型別都是unsigned int(無符號整型)!!!

①迴圈緩衝區的大小m設定為2的冪(舉例m=2^4=16)

②初始化隊頭 in=0 ,隊尾 out = 0

③out == in的時候緩衝區為空,(in - out ) == m的時候緩衝區為滿。

④緩衝區的長度len = (in - out)

⑤入隊:a[in & (m-1) ] = data ; in = ++in;

出對:data = a[ out & (m-1) ] ; out = ++out;

⑥因為我們緩衝區的大小m設定為2的冪,而unsigned int 型的溢位值肯定是m的2的冪次倍,也就是我們的unsigned int 能表示的數值範圍就是2的冪數倍個m。所以,當我們需要得到當前in或者out對應於實際分配到記憶體的那塊迴圈緩衝區的哪個位置時,可以讓in或者out跟(m-1)相與;而更新in和out時,只需要++in和++out。

下面舉例說明:

m = 10000;(m設定為16)

(m-1) = 01111; 

由於in和out都是unsigned int資料型別,所以in和out能表示的數值範圍為maxof(unsigned_int)=2^32-1 = 4294967295

a、當out在[0,m-1]範圍內,就設out = 6(0110),out & (m-1) = 0110,也就是6。嗯,這個簡單。

b、當out 在[m,4294967295]範圍內,設out = 28(11100),out & (m-1) = 11100 & 01111 = 01100,也就是out等於28時對應的迴圈緩衝區的位置下標為12。

c、分析一下最極端的情況當out等於unsigned int的最大值4294967295,

out&(m-1)= 01111,也就是迴圈緩衝區的最後乙個位置。

而out+1就溢位了,由於unsigned int溢位時變為0,又從最後乙個位置加到第乙個位置了。

總結:

關鍵字:unsigned int 、按位與運算、2的次冪

a、必須要將m設定為2的次冪。

b、用這種方法不必讓in和out對m取餘,通過與運算,可以提公升速度。

b、unsigned int 溢位時自動變為0,更新in和out時只需要加1即可,方便。

迴圈緩衝區類

乙個迴圈緩衝區的實現類。思路 分配乙個固定緩衝區,利用緩衝區讀寫資料。當寫到緩衝區底部而讀指標不在緩衝區頂部時,則寫指標移動到緩衝區頂部,繼續寫操作。insream.h include pragma once class insream 迴圈堆疊 byte getreadcursor byte ge...

輸入緩衝區與輸出緩衝區

本博文通過一段程式來理解輸入緩衝區與輸出緩衝區。程式如下 author wanghao created time thu 17 may 2018 06 03 12 ampdt file name test.c description include int main int argc,const c...

迴圈利用記憶體 環形緩衝區

備份兩種重複利用記憶體,避免頻繁申請記憶體的方法。databuffer.h ifndef databuffer h define databuffer h define buffer size 1024 初始緩衝區大小 class databuffer endif databuffer hdatab...