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