文章主題
在我們的日常編程中,對(duì)消息隊(duì)列的需求非常常見,使用一個(gè)簡潔、高效的消息隊(duì)列編程模型,對(duì)于代碼邏輯的清晰性,對(duì)于事件處理的高效率來說,是非常重要的。這篇文章就來看看 ZWave 中是通過什么機(jī)制為我們提供了一個(gè)便捷的消息隊(duì)列處理機(jī)制。
內(nèi)容導(dǎo)航
-
消息隊(duì)列是什么
-
我自己寫的消息隊(duì)列
-
ZWave 消息隊(duì)列的結(jié)構(gòu)
-
ZWave 消息隊(duì)列的使用(初始化、存儲(chǔ)消息、取出消息)
消息隊(duì)列是什么
消息隊(duì)列最主要特點(diǎn)是:存儲(chǔ)消息,先進(jìn)先出。
比如在典型的生產(chǎn)者-消費(fèi)者編程模型中,先創(chuàng)建一個(gè)消息隊(duì)列,最大容量是 100。
當(dāng)生產(chǎn)者產(chǎn)生一條消息時(shí),如果消息隊(duì)列未滿,就放進(jìn)消息隊(duì)列的尾部。
消費(fèi)者定期去檢查消息隊(duì)列中是否有消息,如果有,則取出最前面的那條消息進(jìn)行處理,直到把隊(duì)列中的所有消息都處理完。
當(dāng)然,如果鏈表來創(chuàng)建一個(gè)動(dòng)態(tài)的消息隊(duì)列也是可以的,這樣就可以構(gòu)成一個(gè)無容量限制的隊(duì)列,這個(gè)模型有點(diǎn)復(fù)雜,咱們暫且不討論它。
我自己寫的消息隊(duì)列
在我自己的開發(fā)過程中,經(jīng)常需要使用消息隊(duì)列來保存多條消息,每一條消息都存儲(chǔ)長度不等的字符串,于是就自己寫了一個(gè)最簡單的消息隊(duì)列實(shí)現(xiàn)模板,當(dāng)然對(duì)于項(xiàng)目來說也是最合適的,因?yàn)槭橇矿w裁衣嘛。
一共2個(gè)文件(.h, .c),每次項(xiàng)目中需要用到時(shí),就把這2個(gè)文件拷貝過來,再簡單修改一下(保存的每條消息滿足應(yīng)用的需求),就直接用上了。簡單、粗暴、有效、好用,每次都能很塊就解決我的問題。
這里簡單截個(gè)圖,如果需要,我可以免費(fèi)分享!
使用起來也比較簡單,只需要3個(gè)步驟。
ZWave 消息隊(duì)列的結(jié)構(gòu)
ZWave SDK 的每一個(gè) Sample 中已經(jīng)給我們提供了一個(gè)很好的消息隊(duì)列編程模型,不過它還嵌入了一個(gè) task 任務(wù)管理的機(jī)制,后面我會(huì)簡單畫一下 task 的處理邏輯,但是不會(huì)深入探究。
先來看一下 ZWave 提供的消息隊(duì)列的結(jié)構(gòu)。
請(qǐng)注意:這是消息隊(duì)列的結(jié)構(gòu),而這個(gè)隊(duì)列中存儲(chǔ)的每一條消息是存儲(chǔ)在一個(gè)數(shù)組緩沖區(qū)中,通過 array 指針進(jìn)行引用。因此,在消息隊(duì)列初始化的時(shí)候,必須提供一個(gè)數(shù)組,并把數(shù)組的地址賦值給 array 指針。
關(guān)于這個(gè)數(shù)組,從代碼中可以看到 QElementType 其實(shí)就是一個(gè)無符號(hào)字節(jié),因此,這個(gè)消息隊(duì)列僅僅能存儲(chǔ)最最簡單的消息,即:一個(gè)字節(jié)的數(shù)值??梢钥匆幌?SwitchOnOff.c 中所存儲(chǔ)的消息,都是 EVENT_APP 這個(gè)枚舉類型的值。
ZWave 消息隊(duì)列的使用
1.消息隊(duì)列的初始化
在應(yīng)用程序初始化的時(shí)候,ZWave 實(shí)例程序?yàn)槲覀円呀?jīng)創(chuàng)建好一個(gè)消息隊(duì)列了,流程如下。
可以看到,一共有 2 個(gè)消息隊(duì)列:eventQueue 和 jobQueue,這兩個(gè)隊(duì)列的實(shí)現(xiàn)機(jī)制都是一樣的,只不過是把不同類型的消息放在不同的隊(duì)列而已,因此,只要分析其中一個(gè) eventQueue 就可以了。
初始化完成之后,存儲(chǔ)消息的數(shù)組是空的,消息隊(duì)列的有效消息個(gè)數(shù)是 0。
2.存儲(chǔ)消息到消息隊(duì)列
就是把一條新消息放入消息隊(duì)列的數(shù)組中,然后更新消息隊(duì)列的一些狀態(tài)參數(shù),比如:有效消息長度,存儲(chǔ)的這條消息位置等等。
函數(shù)調(diào)用流程如下。
3.從消息隊(duì)列中獲取消息
這個(gè)也很好理解,就是通過消息隊(duì)列的結(jié)構(gòu)檢查一下是否有消息等待處理。如果是的話,就取出消息,并更新消息隊(duì)列的一些狀態(tài)參數(shù)。
函數(shù)調(diào)用流程如下。
ZWave 文檔中已經(jīng)說明,協(xié)議層會(huì)定期調(diào)用應(yīng)用層的函數(shù) ApplicationPoll( ) ,這也是 ZWave 推薦的方式讓應(yīng)用層執(zhí)行自己的邏輯,但是應(yīng)用層不能在這個(gè)函數(shù)中執(zhí)行太長時(shí)間。
在這個(gè)函數(shù)中,我們可以直接去消息隊(duì)列中取出一個(gè)消息。但是如果這么做的話,就浪費(fèi)了 ZWave 為我們提供的 Task 機(jī)制,因此這里調(diào)用了 TaskApplicationPoll( ),然后我們應(yīng)用層的事件處理函數(shù) AppStateManager( ) 就老老實(shí)實(shí)的待著,等待別人把事件消息準(zhǔn)備好、喂過來。
其實(shí),這也是一種分層編程思想,如下。
** 總結(jié) **
現(xiàn)在再回頭看一下 ZWave 的消息隊(duì)列處理機(jī)制,思路非常清晰,而且擴(kuò)充性非常強(qiáng)。
后面我希望自己可以抽一點(diǎn)時(shí)間,把這里的代碼抽取出來,寫一個(gè)通用的、能夠處理一些復(fù)雜消息的消息隊(duì)列機(jī)制,讓開發(fā)過程變得更加愉悅!
-
機(jī)制
+關(guān)注
關(guān)注
0文章
24瀏覽量
9831 -
Zwave
+關(guān)注
關(guān)注
0文章
8瀏覽量
12139 -
消息隊(duì)列
+關(guān)注
關(guān)注
0文章
33瀏覽量
3017
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
FIFO隊(duì)列原理簡述
ZWAVE技術(shù)貼
Linux等待隊(duì)列如何實(shí)現(xiàn)
怎樣去設(shè)計(jì)一種采用覆蓋機(jī)制的FIFO隊(duì)列模型呢
一種高效的磁盤隊(duì)列I/O機(jī)制
iFix組態(tài)軟件中基于隊(duì)列的命令處理機(jī)制研究
基于多級(jí)隊(duì)列的云服務(wù)并發(fā)量分級(jí)緩存機(jī)制
SystemVerilog中的隊(duì)列
單片機(jī)消息隊(duì)列的實(shí)現(xiàn)原理和機(jī)制
![單片機(jī)消息<b class='flag-5'>隊(duì)列</b>的實(shí)現(xiàn)原理和<b class='flag-5'>機(jī)制</b>](https://file1.elecfans.com/web2/M00/88/B6/wKgZomRwEQeAZHOsAAAztrtbyhU714.jpg)
RTOS消息隊(duì)列的應(yīng)用
![RTOS消息<b class='flag-5'>隊(duì)列</b>的應(yīng)用](https://file1.elecfans.com/web2/M00/88/CB/wKgaomR0E0WAGaiCAAAZvY_r7Cs460.png)
FreeRTOS消息隊(duì)列介紹
![FreeRTOS消息<b class='flag-5'>隊(duì)列</b>介紹](https://file1.elecfans.com/web2/M00/8C/25/wKgZomSmgi6AbaURAAJ2j7wCnv4174.jpg)
評(píng)論