一般我們設定乙個緩衝佇列的結構如下
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 測試...