RT-Thread學習記錄15 內存池的使用

以下爲看視頻筆記..........

1. 內存池的介紹

 

動態內存堆可以分配任意大小的內存塊,非常靈活和方便。但其存在明顯的缺點:一是分配效率不高,在每次分配時,都要進行空閒內存塊查找;二是容易產生內存碎片。

爲了提高內存分配的效率,並且避免內存碎片,RT-Thread 提供了另外一種內存管理方法:內存池(Memory Pool )

內存池是一種內存分配方式,用於分配大量大小相同的小內存塊。使用內存池可以極大地加快內存分配與釋放的速度,且能儘量避免內存碎片化。

RT-Thread的內存池支持線程掛起功能,當內存池中無空閒內存塊時,申請線程會被掛起,直到內存池中有新的可用內存塊,再將掛起的線程喚醒。基於這個特點內存池非常適合需要通過內存資源進行同步的場景。

2. 內存池工作機制

 

內存池在創建時先從系統中獲取一大塊內存 ( 靜態或動態),然後分成相同大小的多個小內存塊,這些小內存塊通過鏈表連接起來(此鏈表也稱爲空閒鏈表)。線程每次申請分配內存塊的時候,系統從空閒鏈表中取出鏈頭上第一個內存塊, 提供給申請者。

3. 內存池控制塊

在RT_Thread中,內存池控制塊是操作系統用於管理內存池的一個數據結構。

struct  rt_mempool
{
    struct rt_object  parent:
    void         *start_address;//保存申請的內存的地址
    rt_size_t         size;     //記錄大內存塊的大小
    rt_size_t         block_size; //記錄大內存塊中小內存塊的大小
    rt_uint8_t        *block_list; //小內存塊的列表
    rt_size_t      block_total_count;//總共有多少小內存塊
    rt_size_t      block_free_count;  //當前小內存塊空閒的個數
    rt_list_t      suspend_thread;  //內存塊支持掛起,記錄線程掛起在內存池上的列表
    rt_size_t      suspend_thread_count;//記錄線程掛起在內存池上的數目
}
typedef  struct  rt_mempool  *rt_mp_t  //內存塊的指針型定義

定義靜態內存池:struct  rt_mempool  static_mp

定義動態內存池:rt_mp_t  dynamic_mp

4.  內存池的操作

靜態內存池的初始化與脫離

rt_err_t  rt_mp_init(struct rt_mempool  *mp,const  char  *name,
                    void  *start,rt_size_t  size,rt_size_t  block_size)
//第一個參數爲內存控制塊的地址,第二個參數爲內存控制塊起一個名字,注意RT-Thread的所有對象都要起一個名稱。第三個參數爲系統的內存地址輸入給參數,可以先用數組的方式定義出來。第四個參數爲內存池的大小。第五個參數爲內存池中內存塊的大小(數值爲4的整數倍)。計算內存池中有多少內存塊:
//size/(block_size+4).內存塊都是用鏈表連接的,4是一個指針的長度
rt_err_t  rt_mp_detach(struct  rt_mempool  *mp)
//第二個參數爲內存塊數目。第三個參數爲內存塊的大小

動態內存池的創建與刪除

rt_mp_t  rt_mp_create(const char *name,rt_size_t  block_count,rt_size_t  block_size)

rt_err_t  rt_mp_delete(rt_mp_t  mp)

申請內存塊

void  rt_mp_alloc(rt_mp_t mp ,rt_int32_t time)
//第一個參數爲內存塊控制塊的地址,指示從哪個內存池分配內存控制塊,第二個參數爲當內存池滿時線程掛起時間,當time>0,掛起time 時間,當time = 0,立即返回,time < 0 ,線程阻塞在內存池的申請上。

釋放內存塊

void rt_mp_free(void *block)//輸入內存塊的地址,釋放那個內存塊

5. 例程在memp_sample.c

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章