迴圈緩衝佇列的思考

2021-07-11 23:34:11 字數 2287 閱讀 1928

一般我們設定乙個緩衝佇列的結構如下

struct queue

queue;

這一類佇列緩衝區只能進行單個位元組的儲存操作,而對多位元組的結構體或32位的int操作,需要重新寫重複的函式來實現,本來一次就能做好的事情非得讓人做n次,是會很讓人火氣的,難道就沒有個模板可以對各種型別的結構進行儲存嗎?就想c++的容器那樣,只要定義了型別就可以用相同的函式直接操作,只是操作的物件不同,就可以實現不同效果的儲存訪問。

當然有,下面就來看這種佇列結構,

struct queue

queue;

佇列中定義了單個元素的儲存空間的大小,其初始化函式如下:

queue * queue_init(uint16_t elem_num,uint8_t elem_size);

elem_num為初始化佇列的成員個數,elem_size為成員的所佔空間的大小,以位元組為單位.

如想定義int型的緩衝佇列,成員100個,則***x_ptr=queue_init(100,sizeof(int));最後返回佇列的緩衝區空間的首位址.

如想定義struct結構體型別的緩衝佇列,成員100個,則

struct *** ***x_ptr= queue_init(100,sizeof(struct ***));

但有時候我想對這個緩衝佇列同時進行push in操作,但有時候程式**又不知道什麼時候進行了pop out操作,因為這種緩衝佇列一般是互斥資源,不允許這樣的操作,會很容易造成非法訪問記憶體位址的錯誤,造成佇列儲存的損壞。

no作 no death,互斥資源是不能同時訪問的,你自己作也沒辦法,估計有人會這麼想,實際我也這麼想過,嘿嘿.

但實際有時候,不是我們不想互斥的訪問緩衝佇列,而是迫不得己,例如我正在主函式中取緩衝佇列的資料進行處理,恰好此時接收中斷發生,需要向緩衝佇列中存放資料,天哪,同時訪問互斥資源緩衝佇列的情況發生了,這哪是我想要的啊,天地可證。

那就加鎖唄,這是個好方法嗎?姑且試一下,對緩衝佇列的處理部分加鎖,但恰此時接收中斷發生時,加了鎖,就沒法對接收緩衝區佇列訪問,你讓我把資料往哪放,資料又不能丟棄.

怎麼辦?

再寫個緩衝佇列,臨時存放接收的資料,等緩衝佇列的處理結束後,我再把臨時緩衝佇列的資料copy到緩衝佇列中,那對臨時緩衝佇列的pop out操作時,也有可能此時也發生了中斷,那怎麼操作,臨時緩衝佇列被上鎖占用,往緩衝佇列中存放資料,那接收資料的順序不就亂了嗎,怎麼辦,還是需要對乙個緩衝佇列同時進行push in和pop out操作,所謂的把佇列作為互斥資源,是因為佇列的結構體定義中,存在互斥的變數成員.

再看下緩衝佇列的結構體定義

struct queue

queue;

看下是誰有可能被push in和pop out操作時同時訪問,且會改變其值的成員變數,只有count,push in時,我要增加count的值,pop out時我要減少count的值。那下面就討論下 如何做才能對互斥的count同時操作,而對緩衝佇列沒有任何危害。要麼直接就把count這個成員變數直接拿掉,不要了。不要就不會有問題了。

結構就變成這樣了

struct queue

queue;

那現在的問題就是考慮一下下面兩個問題。

1:佇列的空滿問題

對於佇列的空滿,用乙個標誌量is_empty變數表示,或浪費佇列中乙個儲存空間表示

對於第一種方法,需要在每次對迴圈佇列push in 和pop out操作退出前,都要對is_empty變數更改其值。(如果選擇這種)

不可行,因為is_empty也是互斥的資源,需要在push in 和pop out操作中改變這個成員的值.

那只能選擇最後乙個方法:浪費乙個儲存空間的方法

queue_ptr->front ==(queue_ptr->rear+queue_ptr->elem_size)%queue_ptr->buffer_size;

即如果定義乙個乙個佇列的儲存值是count,然其實際只能儲存count-1個值。

2:佇列的儲存長度獲取問題

(queue_ptr->rear+queue_ptr->buffer_size-queue_ptr->front)%queue_ptr->buffer_size/ queue_ptr->elem_size;

通過對這個迴圈佇列的操作,我們就可以同時對乙個佇列進行pop的操作時,也可以進行push操作,但是不允許兩個pop操作或push操作同時發生。

參考**:

字元裝置驅動之Buttons 迴圈緩衝佇列

buttons.c include include include include include include include include include include include include include include static int major 0 static st...

雙緩衝佇列

前段時間,做了個 雙緩衝佇列 可是測試的效果就是不怎麼明顯,理論完全都在這裡,可是就是看不到效果。昨天在胡總的提示下,終於意識到不該用阻塞佇列,換成普通的list物件,這樣效果就明顯多啦 又重新寫了一篇文件,如下 好,31毫秒。這是我們的第一種解決方法,下面再來看第二種解決方法 其實我們在facto...

雙緩衝佇列

例一 首先,使用arrayblockingqueue類建立乙個大小為10的雙緩衝佇列queue 然後,迴圈20次向佇列queue中新增元素,如果5秒內元素仍沒有入隊到佇列中,則返回false 如下 public class demo03 catch interruptedexception e 測試...