1. 程式人生 > >11.記憶體池//依據RT-Thread核心程式設計的學習記錄(非核心實現)

11.記憶體池//依據RT-Thread核心程式設計的學習記錄(非核心實現)

記憶體池,申請出得記憶體情況是記憶體塊,相對於動態記憶體申請rt_malloc()申請的記憶體,rt_mp_alloc()申請的記憶體塊的開頭和結尾會包含指向上一塊的指標和指向下一塊記憶體塊的指標。每塊記憶體塊的大小相等。動態申請記憶體不會出現任務排程,記憶體池申請記憶體會出現任務排程。

1.初始化記憶體池物件

/*靜態初始化記憶體池物件*/
static rt_uint8_t *ptr[50];
static rt_uint8_t static_mempool[1024];
static struct rt_mempool static_mp;

rt_mp_init(&static_mp, "name", &static_mempool[0], sizeof(static_mempool), size of each memory blocks);

/*動態初始化記憶體池物件*/
static rt_uint8_t *ptr[50];
static rt_mp_t dynamic_mp = RT_NULL;

dynamic_mp = rt_mp_creat("name",the count of memory blocks,the size of each memory blocks);


2.記憶體池的申請和釋放

/*記憶體池的申請*/
static uint8_t ptr[xx];

ptr[i] = rt_mp_alloc(&static_mp, time);

ptr[i] = rt_mp_alloc(dynamic_mp, time);

/*記憶體池的釋放*/

rt_mp_free(&ptr[i]);

3.刪除記憶體池物件

/*刪除記憶體池物件*/


rt_mp_detach(&static_mp);

rt_mp_delete(dynamic_mp);

4.例程

/*
 * 程式清單:記憶體池例程
 *
 * 這個程式會建立一個靜態的記憶體池物件,2個動態執行緒。
 * 一個執行緒會試圖從記憶體池中獲得記憶體塊,另一個執行緒釋放記憶體塊
 * 記憶體塊
 */
#include <rtthread.h>

static rt_uint8_t *ptr[50];
static rt_uint8_t mempool[1024];
static struct rt_mempool mp;

#define THREAD_PRIORITY      25
#define THREAD_STACK_SIZE    512
#define THREAD_TIMESLICE     5

/* 指向執行緒控制塊的指標 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;

/* 執行緒1入口 */
static void thread1_mp_alloc(void *parameter)
{
    int i;
    for (i = 0 ; i < 15 ; i++)
    {
        if (ptr[i] == RT_NULL)
        {
            /* 試圖申請記憶體塊50次,當申請不到記憶體塊時,
               執行緒1掛起,轉至執行緒2執行 */
            ptr[i] = rt_mp_alloc(&mp, RT_WAITING_FOREVER);
            if (ptr[i] != RT_NULL)
                rt_kprintf("allocate No.%d\n", i);
        }
    }
}

/* 執行緒2入口,執行緒2的優先順序比執行緒1低,應該執行緒1先獲得執行。*/
static void thread2_mp_release(void *parameter)
{
    int i;

    rt_kprintf("thread2 try to release block\n");
    for (i = 0; i < 15 ; i++)
    {
        /* 釋放所有分配成功的記憶體塊 */
        if (ptr[i] != RT_NULL)
        {
            rt_kprintf("release block %d\n", i);
            rt_mp_free(ptr[i]);
            ptr[i] = RT_NULL;
        }
    }
}

int mempool_sample(void)
{
    int i;
    for (i = 0; i < 50; i ++) ptr[i] = RT_NULL;        //懼怕野指標

    /* 初始化記憶體池物件 */
    rt_mp_init(&mp, "mp1", &mempool[0], sizeof(mempool), 80);

    /* 建立執行緒1:申請記憶體池 */
    tid1 = rt_thread_create("thread1", thread1_mp_alloc, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE);
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);


    /* 建立執行緒2:釋放記憶體池*/
    tid2 = rt_thread_create("thread2", thread2_mp_release, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY + 1, THREAD_TIMESLICE);
    if (tid2 != RT_NULL)
        rt_thread_startup(tid2);

    return 0;
}


/*程式列印結果*/
/*
allocate No.0

allocate No.1

allocate No.2

allocate No.3

allocate No.4

allocate No.5

allocate No.6

allocate No.7

allocate No.8

allocate No.9

allocate No.10

allocate No.11

thread2 try to release block

release block 0

allocate No.12

release block 1

allocate No.13

release block 2

allocate No.14

release block 3

release block 4

release block 5

release block 6

release block 7

release block 8

release block 9

release block 10

release block 11

release block 12

release block 13

release block 14

*/

列印中,記憶體塊未申請到第13塊記憶體導致排程等待,由此執行緒2開啟,開始刪除記憶體塊。為什麼是第13塊申請不到,是因為記憶體池的首位均包含一個指標,所以表面從記憶體池的初始化是80個一個空間,實際上是84。1024 / 84 = 12 ,所以想要獲取到記憶體塊必須要等待排程。