關(guān)于內(nèi)存,要講的東西有點(diǎn)多,還是分篇聊吧,這一篇筆記說是講事件,其實(shí)是想借著事件來講一下內(nèi)存管理,正好事件這塊也用到了內(nèi)存管理,所以就一塊講了吧,水平有限,講到哪里算哪里吧,講不到的地方就靠你們了。站在應(yīng)用的角度上來講,開發(fā)一款軟件,當(dāng)你的構(gòu)架定型的時(shí)候,狀態(tài)機(jī)也就基本定型了,能控制事件的數(shù)量和大小,那就取決于你對(duì)狀態(tài)機(jī)的應(yīng)用能力了。但是有一點(diǎn)無論你的事件控制的多小,他總歸會(huì)占很大一部分比重,因?yàn)檎麄€(gè)應(yīng)用所有的交互全靠事件來驅(qū)動(dòng)。
假如你用傳統(tǒng)的方式定義了所有的事件,所謂傳統(tǒng)的方式就是靜態(tài)的定義,你要問啥是靜態(tài)的定義,那么這么講,你這么問就證明你現(xiàn)在用的方式都是靜態(tài)的,那么后面的內(nèi)容都不用講了,直接下課了,因?yàn)殪o態(tài)定義的變量(單片機(jī)中常這么稱呼),從出生開始就不會(huì)凋零,也就是不會(huì)GAMEOVER,那你還談什么生命周期,內(nèi)存回收。內(nèi)存管理?沒有內(nèi)存管理了(那還聊什么,友誼的小船說翻就翻,掀桌子...)。
傳統(tǒng)的靜態(tài)的定義事件,也并不是一無是處,例如,穩(wěn)定,不會(huì)產(chǎn)生系統(tǒng)潛在的風(fēng)險(xiǎn),申請(qǐng)不到,提前回收等等問題,說白了,就是用起來簡(jiǎn)單,不用想那么多復(fù)雜的場(chǎng)景,但是有個(gè)最大的缺點(diǎn)就是消耗內(nèi)存,當(dāng)然這個(gè)問題嵌入式領(lǐng)域,完全可以通過升級(jí)內(nèi)存來解決,這也意味著成本的上升,那全部定義成動(dòng)態(tài)事件?也會(huì)存在很多問題,首先他無形的提高了對(duì)編程者的水平要求,各種漏洞總是五花八門,合理的分配靜態(tài)和動(dòng)態(tài)事件所占的比例,用有限的資源實(shí)現(xiàn)整個(gè)應(yīng)用,才是我們真正的追求。那什么樣子的事件適合被定義為靜態(tài)事件.
這里總結(jié)了一下,給大家兩個(gè)建議:
1. 這個(gè)事件從定義開始,就不會(huì)發(fā)生任何變化,也就是事件的參數(shù)不會(huì)發(fā)生改變。
2. 這個(gè)事件總是被頻繁的使用,貫穿整個(gè)應(yīng)用,例如由QF_tick產(chǎn)生的周期事件。
為了增加應(yīng)用的靈活性,掌握動(dòng)態(tài)事件的使用時(shí)關(guān)鍵,下面聊得都是以動(dòng)態(tài)事件為基礎(chǔ)的內(nèi)存方案。
接下來我們來聊聊,關(guān)于事件是如何在QF中傳遞的,我們知道事件要被發(fā)送到相應(yīng)的事件隊(duì)列,那么真正傳遞到事件隊(duì)列的是什么?其實(shí)是有兩種方案,第一種是值傳遞,這種情況,你要傳遞一個(gè)事件,你就需要把整個(gè)事件復(fù)制出一個(gè)復(fù)制品,并放進(jìn)事件隊(duì)列中,實(shí)際情況比這還要復(fù)雜,這只是將事件傳遞到事件隊(duì)列,還有事件循環(huán)要從事件隊(duì)列取出事件,給到狀態(tài)機(jī),這中間是否有牽扯一次的事件復(fù)制,在很多RTOS中都是采用這種值傳遞,他的好處是用內(nèi)存開銷來?yè)Q取確定性,其存取模型如圖:
還有一種事件的派發(fā)機(jī)制,叫做零事件派發(fā)機(jī)制,實(shí)際就是應(yīng)用指針傳遞,這種方式不太適合傳統(tǒng)的RTOS這里記住就好了,展開講就太細(xì)節(jié)了,但是這種方式非常適合QF框架,因?yàn)樗敲黠@的控制倒置的類型,框架對(duì)于維護(hù)事件的指針還是合適的,因?yàn)榭蚣芸梢詮念^到尾的跟蹤整個(gè)事件指針的來龍去脈,不會(huì)再RTC中過多的停留。其存取模型如圖:
從圖中可以看到動(dòng)態(tài)事件全部被指向事件池,也就是在傳遞過程中傳遞的是指針。還有一個(gè)點(diǎn)需要關(guān)注一下,就是一個(gè)動(dòng)態(tài)事件的生命周期中所有權(quán)的問題,直接看圖吧,大概理解一下圖:
關(guān)于內(nèi)存管理再講篇幅就有點(diǎn)長(zhǎng)了,還是分開聊,看下篇吧 。